/* AES Cipher

Copyright (C) 2002, Dr. Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
All rights reserved.

LICENSE TERMS

The free distribution and use of this software in both source and binary
form is allowed (with or without changes) provided that:

  1. distributions of this source code include the above copyright
     notice, this list of conditions and the following disclaimer;

  2. distributions in binary form include the above copyright
     notice, this list of conditions and the following disclaimer
     in the documentation and/or other associated materials;

  3. the copyright holder's name is not used to endorse products
     built using this software without specific written permission.

ALTERNATIVELY, provided that this notice is retained in full, this product
may be distributed under the terms of the GNU General Public License (GPL),
in which case the provisions of the GPL apply INSTEAD OF those given above.

DISCLAIMER

This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.

Copyright (C) Alexander Kjeldaas.
Copyright (C) Herbert Valerio Riedel.
Copyright (C) Kyle McMartin.
Copyright (C) Adam J. Richter.
Copyright (C) 2011-2018 Manuel Sainz de Baranda y Goñi.
Released under the terms of the GNU Lesser General Public License v3. */

#if defined(CIPHER_AES_HIDE_API)
#	define CIPHER_AES_API static
#elif defined(CIPHER_AES_STATIC)
#	define CIPHER_AES_API
#else
#	define CIPHER_AES_API Z_API_EXPORT
#endif

#if defined(CIPHER_AES_HIDE_ABI)
#	define CIPHER_AES_ABI static
#elif defined(CIPHER_AES_STATIC)
#	define CIPHER_AES_ABI
#else
#	define CIPHER_AES_ABI Z_API_EXPORT
#endif

#define CIPHER_AES_API_OMIT_FUNCTION_PROTOTYPES

#if defined(CIPHER_AES_USE_LOCAL_HEADER)
#	include "AES.h"
#else
#	include <cipher/AES.h>
#endif

#include <Z/functions/base/value.h>

#define C(value) Z_UINT32(0x##value)

static const zuint32 rco[10] = {1, 2, 4, 8, 16, 32, 64, 128, 27, 54};

static zuint32 const ft[4][256] = {
	{C(A56363C6), C(847C7CF8), C(997777EE), C(8D7B7BF6),
	 C(0DF2F2FF), C(BD6B6BD6), C(B16F6FDE), C(54C5C591),
	 C(50303060), C(03010102), C(A96767CE), C(7D2B2B56),
	 C(19FEFEE7), C(62D7D7B5), C(E6ABAB4D), C(9A7676EC),
	 C(45CACA8F), C(9D82821F), C(40C9C989), C(877D7DFA),
	 C(15FAFAEF), C(EB5959B2), C(C947478E), C(0BF0F0FB),
	 C(ECADAD41), C(67D4D4B3), C(FDA2A25F), C(EAAFAF45),
	 C(BF9C9C23), C(F7A4A453), C(967272E4), C(5BC0C09B),
	 C(C2B7B775), C(1CFDFDE1), C(AE93933D), C(6A26264C),
	 C(5A36366C), C(413F3F7E), C(02F7F7F5), C(4FCCCC83),
	 C(5C343468), C(F4A5A551), C(34E5E5D1), C(08F1F1F9),
	 C(937171E2), C(73D8D8AB), C(53313162), C(3F15152A),
	 C(0C040408), C(52C7C795), C(65232346), C(5EC3C39D),
	 C(28181830), C(A1969637), C(0F05050A), C(B59A9A2F),
	 C(0907070E), C(36121224), C(9B80801B), C(3DE2E2DF),
	 C(26EBEBCD), C(6927274E), C(CDB2B27F), C(9F7575EA),
	 C(1B090912), C(9E83831D), C(742C2C58), C(2E1A1A34),
	 C(2D1B1B36), C(B26E6EDC), C(EE5A5AB4), C(FBA0A05B),
	 C(F65252A4), C(4D3B3B76), C(61D6D6B7), C(CEB3B37D),
	 C(7B292952), C(3EE3E3DD), C(712F2F5E), C(97848413),
	 C(F55353A6), C(68D1D1B9), C(00000000), C(2CEDEDC1),
	 C(60202040), C(1FFCFCE3), C(C8B1B179), C(ED5B5BB6),
	 C(BE6A6AD4), C(46CBCB8D), C(D9BEBE67), C(4B393972),
	 C(DE4A4A94), C(D44C4C98), C(E85858B0), C(4ACFCF85),
	 C(6BD0D0BB), C(2AEFEFC5), C(E5AAAA4F), C(16FBFBED),
	 C(C5434386), C(D74D4D9A), C(55333366), C(94858511),
	 C(CF45458A), C(10F9F9E9), C(06020204), C(817F7FFE),
	 C(F05050A0), C(443C3C78), C(BA9F9F25), C(E3A8A84B),
	 C(F35151A2), C(FEA3A35D), C(C0404080), C(8A8F8F05),
	 C(AD92923F), C(BC9D9D21), C(48383870), C(04F5F5F1),
	 C(DFBCBC63), C(C1B6B677), C(75DADAAF), C(63212142),
	 C(30101020), C(1AFFFFE5), C(0EF3F3FD), C(6DD2D2BF),
	 C(4CCDCD81), C(140C0C18), C(35131326), C(2FECECC3),
	 C(E15F5FBE), C(A2979735), C(CC444488), C(3917172E),
	 C(57C4C493), C(F2A7A755), C(827E7EFC), C(473D3D7A),
	 C(AC6464C8), C(E75D5DBA), C(2B191932), C(957373E6),
	 C(A06060C0), C(98818119), C(D14F4F9E), C(7FDCDCA3),
	 C(66222244), C(7E2A2A54), C(AB90903B), C(8388880B),
	 C(CA46468C), C(29EEEEC7), C(D3B8B86B), C(3C141428),
	 C(79DEDEA7), C(E25E5EBC), C(1D0B0B16), C(76DBDBAD),
	 C(3BE0E0DB), C(56323264), C(4E3A3A74), C(1E0A0A14),
	 C(DB494992), C(0A06060C), C(6C242448), C(E45C5CB8),
	 C(5DC2C29F), C(6ED3D3BD), C(EFACAC43), C(A66262C4),
	 C(A8919139), C(A4959531), C(37E4E4D3), C(8B7979F2),
	 C(32E7E7D5), C(43C8C88B), C(5937376E), C(B76D6DDA),
	 C(8C8D8D01), C(64D5D5B1), C(D24E4E9C), C(E0A9A949),
	 C(B46C6CD8), C(FA5656AC), C(07F4F4F3), C(25EAEACF),
	 C(AF6565CA), C(8E7A7AF4), C(E9AEAE47), C(18080810),
	 C(D5BABA6F), C(887878F0), C(6F25254A), C(722E2E5C),
	 C(241C1C38), C(F1A6A657), C(C7B4B473), C(51C6C697),
	 C(23E8E8CB), C(7CDDDDA1), C(9C7474E8), C(211F1F3E),
	 C(DD4B4B96), C(DCBDBD61), C(868B8B0D), C(858A8A0F),
	 C(907070E0), C(423E3E7C), C(C4B5B571), C(AA6666CC),
	 C(D8484890), C(05030306), C(01F6F6F7), C(120E0E1C),
	 C(A36161C2), C(5F35356A), C(F95757AE), C(D0B9B969),
	 C(91868617), C(58C1C199), C(271D1D3A), C(B99E9E27),
	 C(38E1E1D9), C(13F8F8EB), C(B398982B), C(33111122),
	 C(BB6969D2), C(70D9D9A9), C(898E8E07), C(A7949433),
	 C(B69B9B2D), C(221E1E3C), C(92878715), C(20E9E9C9),
	 C(49CECE87), C(FF5555AA), C(78282850), C(7ADFDFA5),
	 C(8F8C8C03), C(F8A1A159), C(80898909), C(170D0D1A),
	 C(DABFBF65), C(31E6E6D7), C(C6424284), C(B86868D0),
	 C(C3414182), C(B0999929), C(772D2D5A), C(110F0F1E),
	 C(CBB0B07B), C(FC5454A8), C(D6BBBB6D), C(3A16162C)},

	{C(6363C6A5), C(7C7CF884), C(7777EE99), C(7B7BF68D),
	 C(F2F2FF0D), C(6B6BD6BD), C(6F6FDEB1), C(C5C59154),
	 C(30306050), C(01010203), C(6767CEA9), C(2B2B567D),
	 C(FEFEE719), C(D7D7B562), C(ABAB4DE6), C(7676EC9A),
	 C(CACA8F45), C(82821F9D), C(C9C98940), C(7D7DFA87),
	 C(FAFAEF15), C(5959B2EB), C(47478EC9), C(F0F0FB0B),
	 C(ADAD41EC), C(D4D4B367), C(A2A25FFD), C(AFAF45EA),
	 C(9C9C23BF), C(A4A453F7), C(7272E496), C(C0C09B5B),
	 C(B7B775C2), C(FDFDE11C), C(93933DAE), C(26264C6A),
	 C(36366C5A), C(3F3F7E41), C(F7F7F502), C(CCCC834F),
	 C(3434685C), C(A5A551F4), C(E5E5D134), C(F1F1F908),
	 C(7171E293), C(D8D8AB73), C(31316253), C(15152A3F),
	 C(0404080C), C(C7C79552), C(23234665), C(C3C39D5E),
	 C(18183028), C(969637A1), C(05050A0F), C(9A9A2FB5),
	 C(07070E09), C(12122436), C(80801B9B), C(E2E2DF3D),
	 C(EBEBCD26), C(27274E69), C(B2B27FCD), C(7575EA9F),
	 C(0909121B), C(83831D9E), C(2C2C5874), C(1A1A342E),
	 C(1B1B362D), C(6E6EDCB2), C(5A5AB4EE), C(A0A05BFB),
	 C(5252A4F6), C(3B3B764D), C(D6D6B761), C(B3B37DCE),
	 C(2929527B), C(E3E3DD3E), C(2F2F5E71), C(84841397),
	 C(5353A6F5), C(D1D1B968), C(00000000), C(EDEDC12C),
	 C(20204060), C(FCFCE31F), C(B1B179C8), C(5B5BB6ED),
	 C(6A6AD4BE), C(CBCB8D46), C(BEBE67D9), C(3939724B),
	 C(4A4A94DE), C(4C4C98D4), C(5858B0E8), C(CFCF854A),
	 C(D0D0BB6B), C(EFEFC52A), C(AAAA4FE5), C(FBFBED16),
	 C(434386C5), C(4D4D9AD7), C(33336655), C(85851194),
	 C(45458ACF), C(F9F9E910), C(02020406), C(7F7FFE81),
	 C(5050A0F0), C(3C3C7844), C(9F9F25BA), C(A8A84BE3),
	 C(5151A2F3), C(A3A35DFE), C(404080C0), C(8F8F058A),
	 C(92923FAD), C(9D9D21BC), C(38387048), C(F5F5F104),
	 C(BCBC63DF), C(B6B677C1), C(DADAAF75), C(21214263),
	 C(10102030), C(FFFFE51A), C(F3F3FD0E), C(D2D2BF6D),
	 C(CDCD814C), C(0C0C1814), C(13132635), C(ECECC32F),
	 C(5F5FBEE1), C(979735A2), C(444488CC), C(17172E39),
	 C(C4C49357), C(A7A755F2), C(7E7EFC82), C(3D3D7A47),
	 C(6464C8AC), C(5D5DBAE7), C(1919322B), C(7373E695),
	 C(6060C0A0), C(81811998), C(4F4F9ED1), C(DCDCA37F),
	 C(22224466), C(2A2A547E), C(90903BAB), C(88880B83),
	 C(46468CCA), C(EEEEC729), C(B8B86BD3), C(1414283C),
	 C(DEDEA779), C(5E5EBCE2), C(0B0B161D), C(DBDBAD76),
	 C(E0E0DB3B), C(32326456), C(3A3A744E), C(0A0A141E),
	 C(494992DB), C(06060C0A), C(2424486C), C(5C5CB8E4),
	 C(C2C29F5D), C(D3D3BD6E), C(ACAC43EF), C(6262C4A6),
	 C(919139A8), C(959531A4), C(E4E4D337), C(7979F28B),
	 C(E7E7D532), C(C8C88B43), C(37376E59), C(6D6DDAB7),
	 C(8D8D018C), C(D5D5B164), C(4E4E9CD2), C(A9A949E0),
	 C(6C6CD8B4), C(5656ACFA), C(F4F4F307), C(EAEACF25),
	 C(6565CAAF), C(7A7AF48E), C(AEAE47E9), C(08081018),
	 C(BABA6FD5), C(7878F088), C(25254A6F), C(2E2E5C72),
	 C(1C1C3824), C(A6A657F1), C(B4B473C7), C(C6C69751),
	 C(E8E8CB23), C(DDDDA17C), C(7474E89C), C(1F1F3E21),
	 C(4B4B96DD), C(BDBD61DC), C(8B8B0D86), C(8A8A0F85),
	 C(7070E090), C(3E3E7C42), C(B5B571C4), C(6666CCAA),
	 C(484890D8), C(03030605), C(F6F6F701), C(0E0E1C12),
	 C(6161C2A3), C(35356A5F), C(5757AEF9), C(B9B969D0),
	 C(86861791), C(C1C19958), C(1D1D3A27), C(9E9E27B9),
	 C(E1E1D938), C(F8F8EB13), C(98982BB3), C(11112233),
	 C(6969D2BB), C(D9D9A970), C(8E8E0789), C(949433A7),
	 C(9B9B2DB6), C(1E1E3C22), C(87871592), C(E9E9C920),
	 C(CECE8749), C(5555AAFF), C(28285078), C(DFDFA57A),
	 C(8C8C038F), C(A1A159F8), C(89890980), C(0D0D1A17),
	 C(BFBF65DA), C(E6E6D731), C(424284C6), C(6868D0B8),
	 C(414182C3), C(999929B0), C(2D2D5A77), C(0F0F1E11),
	 C(B0B07BCB), C(5454A8FC), C(BBBB6DD6), C(16162C3A)},

	{C(63C6A563), C(7CF8847C), C(77EE9977), C(7BF68D7B),
	 C(F2FF0DF2), C(6BD6BD6B), C(6FDEB16F), C(C59154C5),
	 C(30605030), C(01020301), C(67CEA967), C(2B567D2B),
	 C(FEE719FE), C(D7B562D7), C(AB4DE6AB), C(76EC9A76),
	 C(CA8F45CA), C(821F9D82), C(C98940C9), C(7DFA877D),
	 C(FAEF15FA), C(59B2EB59), C(478EC947), C(F0FB0BF0),
	 C(AD41ECAD), C(D4B367D4), C(A25FFDA2), C(AF45EAAF),
	 C(9C23BF9C), C(A453F7A4), C(72E49672), C(C09B5BC0),
	 C(B775C2B7), C(FDE11CFD), C(933DAE93), C(264C6A26),
	 C(366C5A36), C(3F7E413F), C(F7F502F7), C(CC834FCC),
	 C(34685C34), C(A551F4A5), C(E5D134E5), C(F1F908F1),
	 C(71E29371), C(D8AB73D8), C(31625331), C(152A3F15),
	 C(04080C04), C(C79552C7), C(23466523), C(C39D5EC3),
	 C(18302818), C(9637A196), C(050A0F05), C(9A2FB59A),
	 C(070E0907), C(12243612), C(801B9B80), C(E2DF3DE2),
	 C(EBCD26EB), C(274E6927), C(B27FCDB2), C(75EA9F75),
	 C(09121B09), C(831D9E83), C(2C58742C), C(1A342E1A),
	 C(1B362D1B), C(6EDCB26E), C(5AB4EE5A), C(A05BFBA0),
	 C(52A4F652), C(3B764D3B), C(D6B761D6), C(B37DCEB3),
	 C(29527B29), C(E3DD3EE3), C(2F5E712F), C(84139784),
	 C(53A6F553), C(D1B968D1), C(00000000), C(EDC12CED),
	 C(20406020), C(FCE31FFC), C(B179C8B1), C(5BB6ED5B),
	 C(6AD4BE6A), C(CB8D46CB), C(BE67D9BE), C(39724B39),
	 C(4A94DE4A), C(4C98D44C), C(58B0E858), C(CF854ACF),
	 C(D0BB6BD0), C(EFC52AEF), C(AA4FE5AA), C(FBED16FB),
	 C(4386C543), C(4D9AD74D), C(33665533), C(85119485),
	 C(458ACF45), C(F9E910F9), C(02040602), C(7FFE817F),
	 C(50A0F050), C(3C78443C), C(9F25BA9F), C(A84BE3A8),
	 C(51A2F351), C(A35DFEA3), C(4080C040), C(8F058A8F),
	 C(923FAD92), C(9D21BC9D), C(38704838), C(F5F104F5),
	 C(BC63DFBC), C(B677C1B6), C(DAAF75DA), C(21426321),
	 C(10203010), C(FFE51AFF), C(F3FD0EF3), C(D2BF6DD2),
	 C(CD814CCD), C(0C18140C), C(13263513), C(ECC32FEC),
	 C(5FBEE15F), C(9735A297), C(4488CC44), C(172E3917),
	 C(C49357C4), C(A755F2A7), C(7EFC827E), C(3D7A473D),
	 C(64C8AC64), C(5DBAE75D), C(19322B19), C(73E69573),
	 C(60C0A060), C(81199881), C(4F9ED14F), C(DCA37FDC),
	 C(22446622), C(2A547E2A), C(903BAB90), C(880B8388),
	 C(468CCA46), C(EEC729EE), C(B86BD3B8), C(14283C14),
	 C(DEA779DE), C(5EBCE25E), C(0B161D0B), C(DBAD76DB),
	 C(E0DB3BE0), C(32645632), C(3A744E3A), C(0A141E0A),
	 C(4992DB49), C(060C0A06), C(24486C24), C(5CB8E45C),
	 C(C29F5DC2), C(D3BD6ED3), C(AC43EFAC), C(62C4A662),
	 C(9139A891), C(9531A495), C(E4D337E4), C(79F28B79),
	 C(E7D532E7), C(C88B43C8), C(376E5937), C(6DDAB76D),
	 C(8D018C8D), C(D5B164D5), C(4E9CD24E), C(A949E0A9),
	 C(6CD8B46C), C(56ACFA56), C(F4F307F4), C(EACF25EA),
	 C(65CAAF65), C(7AF48E7A), C(AE47E9AE), C(08101808),
	 C(BA6FD5BA), C(78F08878), C(254A6F25), C(2E5C722E),
	 C(1C38241C), C(A657F1A6), C(B473C7B4), C(C69751C6),
	 C(E8CB23E8), C(DDA17CDD), C(74E89C74), C(1F3E211F),
	 C(4B96DD4B), C(BD61DCBD), C(8B0D868B), C(8A0F858A),
	 C(70E09070), C(3E7C423E), C(B571C4B5), C(66CCAA66),
	 C(4890D848), C(03060503), C(F6F701F6), C(0E1C120E),
	 C(61C2A361), C(356A5F35), C(57AEF957), C(B969D0B9),
	 C(86179186), C(C19958C1), C(1D3A271D), C(9E27B99E),
	 C(E1D938E1), C(F8EB13F8), C(982BB398), C(11223311),
	 C(69D2BB69), C(D9A970D9), C(8E07898E), C(9433A794),
	 C(9B2DB69B), C(1E3C221E), C(87159287), C(E9C920E9),
	 C(CE8749CE), C(55AAFF55), C(28507828), C(DFA57ADF),
	 C(8C038F8C), C(A159F8A1), C(89098089), C(0D1A170D),
	 C(BF65DABF), C(E6D731E6), C(4284C642), C(68D0B868),
	 C(4182C341), C(9929B099), C(2D5A772D), C(0F1E110F),
	 C(B07BCBB0), C(54A8FC54), C(BB6DD6BB), C(162C3A16)},

	{C(C6A56363), C(F8847C7C), C(EE997777), C(F68D7B7B),
	 C(FF0DF2F2), C(D6BD6B6B), C(DEB16F6F), C(9154C5C5),
	 C(60503030), C(02030101), C(CEA96767), C(567D2B2B),
	 C(E719FEFE), C(B562D7D7), C(4DE6ABAB), C(EC9A7676),
	 C(8F45CACA), C(1F9D8282), C(8940C9C9), C(FA877D7D),
	 C(EF15FAFA), C(B2EB5959), C(8EC94747), C(FB0BF0F0),
	 C(41ECADAD), C(B367D4D4), C(5FFDA2A2), C(45EAAFAF),
	 C(23BF9C9C), C(53F7A4A4), C(E4967272), C(9B5BC0C0),
	 C(75C2B7B7), C(E11CFDFD), C(3DAE9393), C(4C6A2626),
	 C(6C5A3636), C(7E413F3F), C(F502F7F7), C(834FCCCC),
	 C(685C3434), C(51F4A5A5), C(D134E5E5), C(F908F1F1),
	 C(E2937171), C(AB73D8D8), C(62533131), C(2A3F1515),
	 C(080C0404), C(9552C7C7), C(46652323), C(9D5EC3C3),
	 C(30281818), C(37A19696), C(0A0F0505), C(2FB59A9A),
	 C(0E090707), C(24361212), C(1B9B8080), C(DF3DE2E2),
	 C(CD26EBEB), C(4E692727), C(7FCDB2B2), C(EA9F7575),
	 C(121B0909), C(1D9E8383), C(58742C2C), C(342E1A1A),
	 C(362D1B1B), C(DCB26E6E), C(B4EE5A5A), C(5BFBA0A0),
	 C(A4F65252), C(764D3B3B), C(B761D6D6), C(7DCEB3B3),
	 C(527B2929), C(DD3EE3E3), C(5E712F2F), C(13978484),
	 C(A6F55353), C(B968D1D1), C(00000000), C(C12CEDED),
	 C(40602020), C(E31FFCFC), C(79C8B1B1), C(B6ED5B5B),
	 C(D4BE6A6A), C(8D46CBCB), C(67D9BEBE), C(724B3939),
	 C(94DE4A4A), C(98D44C4C), C(B0E85858), C(854ACFCF),
	 C(BB6BD0D0), C(C52AEFEF), C(4FE5AAAA), C(ED16FBFB),
	 C(86C54343), C(9AD74D4D), C(66553333), C(11948585),
	 C(8ACF4545), C(E910F9F9), C(04060202), C(FE817F7F),
	 C(A0F05050), C(78443C3C), C(25BA9F9F), C(4BE3A8A8),
	 C(A2F35151), C(5DFEA3A3), C(80C04040), C(058A8F8F),
	 C(3FAD9292), C(21BC9D9D), C(70483838), C(F104F5F5),
	 C(63DFBCBC), C(77C1B6B6), C(AF75DADA), C(42632121),
	 C(20301010), C(E51AFFFF), C(FD0EF3F3), C(BF6DD2D2),
	 C(814CCDCD), C(18140C0C), C(26351313), C(C32FECEC),
	 C(BEE15F5F), C(35A29797), C(88CC4444), C(2E391717),
	 C(9357C4C4), C(55F2A7A7), C(FC827E7E), C(7A473D3D),
	 C(C8AC6464), C(BAE75D5D), C(322B1919), C(E6957373),
	 C(C0A06060), C(19988181), C(9ED14F4F), C(A37FDCDC),
	 C(44662222), C(547E2A2A), C(3BAB9090), C(0B838888),
	 C(8CCA4646), C(C729EEEE), C(6BD3B8B8), C(283C1414),
	 C(A779DEDE), C(BCE25E5E), C(161D0B0B), C(AD76DBDB),
	 C(DB3BE0E0), C(64563232), C(744E3A3A), C(141E0A0A),
	 C(92DB4949), C(0C0A0606), C(486C2424), C(B8E45C5C),
	 C(9F5DC2C2), C(BD6ED3D3), C(43EFACAC), C(C4A66262),
	 C(39A89191), C(31A49595), C(D337E4E4), C(F28B7979),
	 C(D532E7E7), C(8B43C8C8), C(6E593737), C(DAB76D6D),
	 C(018C8D8D), C(B164D5D5), C(9CD24E4E), C(49E0A9A9),
	 C(D8B46C6C), C(ACFA5656), C(F307F4F4), C(CF25EAEA),
	 C(CAAF6565), C(F48E7A7A), C(47E9AEAE), C(10180808),
	 C(6FD5BABA), C(F0887878), C(4A6F2525), C(5C722E2E),
	 C(38241C1C), C(57F1A6A6), C(73C7B4B4), C(9751C6C6),
	 C(CB23E8E8), C(A17CDDDD), C(E89C7474), C(3E211F1F),
	 C(96DD4B4B), C(61DCBDBD), C(0D868B8B), C(0F858A8A),
	 C(E0907070), C(7C423E3E), C(71C4B5B5), C(CCAA6666),
	 C(90D84848), C(06050303), C(F701F6F6), C(1C120E0E),
	 C(C2A36161), C(6A5F3535), C(AEF95757), C(69D0B9B9),
	 C(17918686), C(9958C1C1), C(3A271D1D), C(27B99E9E),
	 C(D938E1E1), C(EB13F8F8), C(2BB39898), C(22331111),
	 C(D2BB6969), C(A970D9D9), C(07898E8E), C(33A79494),
	 C(2DB69B9B), C(3C221E1E), C(15928787), C(C920E9E9),
	 C(8749CECE), C(AAFF5555), C(50782828), C(A57ADFDF),
	 C(038F8C8C), C(59F8A1A1), C(09808989), C(1A170D0D),
	 C(65DABFBF), C(D731E6E6), C(84C64242), C(D0B86868),
	 C(82C34141), C(29B09999), C(5A772D2D), C(1E110F0F),
	 C(7BCBB0B0), C(A8FC5454), C(6DD6BBBB), C(2C3A1616)}
};

static zuint32 const fl[4][256] = {
	{C(00000063), C(0000007C), C(00000077), C(0000007B),
	 C(000000F2), C(0000006B), C(0000006F), C(000000C5),
	 C(00000030), C(00000001), C(00000067), C(0000002B),
	 C(000000FE), C(000000D7), C(000000AB), C(00000076),
	 C(000000CA), C(00000082), C(000000C9), C(0000007D),
	 C(000000FA), C(00000059), C(00000047), C(000000F0),
	 C(000000AD), C(000000D4), C(000000A2), C(000000AF),
	 C(0000009C), C(000000A4), C(00000072), C(000000C0),
	 C(000000B7), C(000000FD), C(00000093), C(00000026),
	 C(00000036), C(0000003F), C(000000F7), C(000000CC),
	 C(00000034), C(000000A5), C(000000E5), C(000000F1),
	 C(00000071), C(000000D8), C(00000031), C(00000015),
	 C(00000004), C(000000C7), C(00000023), C(000000C3),
	 C(00000018), C(00000096), C(00000005), C(0000009A),
	 C(00000007), C(00000012), C(00000080), C(000000E2),
	 C(000000EB), C(00000027), C(000000B2), C(00000075),
	 C(00000009), C(00000083), C(0000002C), C(0000001A),
	 C(0000001B), C(0000006E), C(0000005A), C(000000A0),
	 C(00000052), C(0000003B), C(000000D6), C(000000B3),
	 C(00000029), C(000000E3), C(0000002F), C(00000084),
	 C(00000053), C(000000D1), C(00000000), C(000000ED),
	 C(00000020), C(000000FC), C(000000B1), C(0000005B),
	 C(0000006A), C(000000CB), C(000000BE), C(00000039),
	 C(0000004A), C(0000004C), C(00000058), C(000000CF),
	 C(000000D0), C(000000EF), C(000000AA), C(000000FB),
	 C(00000043), C(0000004D), C(00000033), C(00000085),
	 C(00000045), C(000000F9), C(00000002), C(0000007F),
	 C(00000050), C(0000003C), C(0000009F), C(000000A8),
	 C(00000051), C(000000A3), C(00000040), C(0000008F),
	 C(00000092), C(0000009D), C(00000038), C(000000F5),
	 C(000000BC), C(000000B6), C(000000DA), C(00000021),
	 C(00000010), C(000000FF), C(000000F3), C(000000D2),
	 C(000000CD), C(0000000C), C(00000013), C(000000EC),
	 C(0000005F), C(00000097), C(00000044), C(00000017),
	 C(000000C4), C(000000A7), C(0000007E), C(0000003D),
	 C(00000064), C(0000005D), C(00000019), C(00000073),
	 C(00000060), C(00000081), C(0000004F), C(000000DC),
	 C(00000022), C(0000002A), C(00000090), C(00000088),
	 C(00000046), C(000000EE), C(000000B8), C(00000014),
	 C(000000DE), C(0000005E), C(0000000B), C(000000DB),
	 C(000000E0), C(00000032), C(0000003A), C(0000000A),
	 C(00000049), C(00000006), C(00000024), C(0000005C),
	 C(000000C2), C(000000D3), C(000000AC), C(00000062),
	 C(00000091), C(00000095), C(000000E4), C(00000079),
	 C(000000E7), C(000000C8), C(00000037), C(0000006D),
	 C(0000008D), C(000000D5), C(0000004E), C(000000A9),
	 C(0000006C), C(00000056), C(000000F4), C(000000EA),
	 C(00000065), C(0000007A), C(000000AE), C(00000008),
	 C(000000BA), C(00000078), C(00000025), C(0000002E),
	 C(0000001C), C(000000A6), C(000000B4), C(000000C6),
	 C(000000E8), C(000000DD), C(00000074), C(0000001F),
	 C(0000004B), C(000000BD), C(0000008B), C(0000008A),
	 C(00000070), C(0000003E), C(000000B5), C(00000066),
	 C(00000048), C(00000003), C(000000F6), C(0000000E),
	 C(00000061), C(00000035), C(00000057), C(000000B9),
	 C(00000086), C(000000C1), C(0000001D), C(0000009E),
	 C(000000E1), C(000000F8), C(00000098), C(00000011),
	 C(00000069), C(000000D9), C(0000008E), C(00000094),
	 C(0000009B), C(0000001E), C(00000087), C(000000E9),
	 C(000000CE), C(00000055), C(00000028), C(000000DF),
	 C(0000008C), C(000000A1), C(00000089), C(0000000D),
	 C(000000BF), C(000000E6), C(00000042), C(00000068),
	 C(00000041), C(00000099), C(0000002D), C(0000000F),
	 C(000000B0), C(00000054), C(000000BB), C(00000016)},

	{C(00006300), C(00007C00), C(00007700), C(00007B00),
	 C(0000F200), C(00006B00), C(00006F00), C(0000C500),
	 C(00003000), C(00000100), C(00006700), C(00002B00),
	 C(0000FE00), C(0000D700), C(0000AB00), C(00007600),
	 C(0000CA00), C(00008200), C(0000C900), C(00007D00),
	 C(0000FA00), C(00005900), C(00004700), C(0000F000),
	 C(0000AD00), C(0000D400), C(0000A200), C(0000AF00),
	 C(00009C00), C(0000A400), C(00007200), C(0000C000),
	 C(0000B700), C(0000FD00), C(00009300), C(00002600),
	 C(00003600), C(00003F00), C(0000F700), C(0000CC00),
	 C(00003400), C(0000A500), C(0000E500), C(0000F100),
	 C(00007100), C(0000D800), C(00003100), C(00001500),
	 C(00000400), C(0000C700), C(00002300), C(0000C300),
	 C(00001800), C(00009600), C(00000500), C(00009A00),
	 C(00000700), C(00001200), C(00008000), C(0000E200),
	 C(0000EB00), C(00002700), C(0000B200), C(00007500),
	 C(00000900), C(00008300), C(00002C00), C(00001A00),
	 C(00001B00), C(00006E00), C(00005A00), C(0000A000),
	 C(00005200), C(00003B00), C(0000D600), C(0000B300),
	 C(00002900), C(0000E300), C(00002F00), C(00008400),
	 C(00005300), C(0000D100), C(00000000), C(0000ED00),
	 C(00002000), C(0000FC00), C(0000B100), C(00005B00),
	 C(00006A00), C(0000CB00), C(0000BE00), C(00003900),
	 C(00004A00), C(00004C00), C(00005800), C(0000CF00),
	 C(0000D000), C(0000EF00), C(0000AA00), C(0000FB00),
	 C(00004300), C(00004D00), C(00003300), C(00008500),
	 C(00004500), C(0000F900), C(00000200), C(00007F00),
	 C(00005000), C(00003C00), C(00009F00), C(0000A800),
	 C(00005100), C(0000A300), C(00004000), C(00008F00),
	 C(00009200), C(00009D00), C(00003800), C(0000F500),
	 C(0000BC00), C(0000B600), C(0000DA00), C(00002100),
	 C(00001000), C(0000FF00), C(0000F300), C(0000D200),
	 C(0000CD00), C(00000C00), C(00001300), C(0000EC00),
	 C(00005F00), C(00009700), C(00004400), C(00001700),
	 C(0000C400), C(0000A700), C(00007E00), C(00003D00),
	 C(00006400), C(00005D00), C(00001900), C(00007300),
	 C(00006000), C(00008100), C(00004F00), C(0000DC00),
	 C(00002200), C(00002A00), C(00009000), C(00008800),
	 C(00004600), C(0000EE00), C(0000B800), C(00001400),
	 C(0000DE00), C(00005E00), C(00000B00), C(0000DB00),
	 C(0000E000), C(00003200), C(00003A00), C(00000A00),
	 C(00004900), C(00000600), C(00002400), C(00005C00),
	 C(0000C200), C(0000D300), C(0000AC00), C(00006200),
	 C(00009100), C(00009500), C(0000E400), C(00007900),
	 C(0000E700), C(0000C800), C(00003700), C(00006D00),
	 C(00008D00), C(0000D500), C(00004E00), C(0000A900),
	 C(00006C00), C(00005600), C(0000F400), C(0000EA00),
	 C(00006500), C(00007A00), C(0000AE00), C(00000800),
	 C(0000BA00), C(00007800), C(00002500), C(00002E00),
	 C(00001C00), C(0000A600), C(0000B400), C(0000C600),
	 C(0000E800), C(0000DD00), C(00007400), C(00001F00),
	 C(00004B00), C(0000BD00), C(00008B00), C(00008A00),
	 C(00007000), C(00003E00), C(0000B500), C(00006600),
	 C(00004800), C(00000300), C(0000F600), C(00000E00),
	 C(00006100), C(00003500), C(00005700), C(0000B900),
	 C(00008600), C(0000C100), C(00001D00), C(00009E00),
	 C(0000E100), C(0000F800), C(00009800), C(00001100),
	 C(00006900), C(0000D900), C(00008E00), C(00009400),
	 C(00009B00), C(00001E00), C(00008700), C(0000E900),
	 C(0000CE00), C(00005500), C(00002800), C(0000DF00),
	 C(00008C00), C(0000A100), C(00008900), C(00000D00),
	 C(0000BF00), C(0000E600), C(00004200), C(00006800),
	 C(00004100), C(00009900), C(00002D00), C(00000F00),
	 C(0000B000), C(00005400), C(0000BB00), C(00001600)},

	{C(00630000), C(007C0000), C(00770000), C(007B0000),
	 C(00F20000), C(006B0000), C(006F0000), C(00C50000),
	 C(00300000), C(00010000), C(00670000), C(002B0000),
	 C(00FE0000), C(00D70000), C(00AB0000), C(00760000),
	 C(00CA0000), C(00820000), C(00C90000), C(007D0000),
	 C(00FA0000), C(00590000), C(00470000), C(00F00000),
	 C(00AD0000), C(00D40000), C(00A20000), C(00AF0000),
	 C(009C0000), C(00A40000), C(00720000), C(00C00000),
	 C(00B70000), C(00FD0000), C(00930000), C(00260000),
	 C(00360000), C(003F0000), C(00F70000), C(00CC0000),
	 C(00340000), C(00A50000), C(00E50000), C(00F10000),
	 C(00710000), C(00D80000), C(00310000), C(00150000),
	 C(00040000), C(00C70000), C(00230000), C(00C30000),
	 C(00180000), C(00960000), C(00050000), C(009A0000),
	 C(00070000), C(00120000), C(00800000), C(00E20000),
	 C(00EB0000), C(00270000), C(00B20000), C(00750000),
	 C(00090000), C(00830000), C(002C0000), C(001A0000),
	 C(001B0000), C(006E0000), C(005A0000), C(00A00000),
	 C(00520000), C(003B0000), C(00D60000), C(00B30000),
	 C(00290000), C(00E30000), C(002F0000), C(00840000),
	 C(00530000), C(00D10000), C(00000000), C(00ED0000),
	 C(00200000), C(00FC0000), C(00B10000), C(005B0000),
	 C(006A0000), C(00CB0000), C(00BE0000), C(00390000),
	 C(004A0000), C(004C0000), C(00580000), C(00CF0000),
	 C(00D00000), C(00EF0000), C(00AA0000), C(00FB0000),
	 C(00430000), C(004D0000), C(00330000), C(00850000),
	 C(00450000), C(00F90000), C(00020000), C(007F0000),
	 C(00500000), C(003C0000), C(009F0000), C(00A80000),
	 C(00510000), C(00A30000), C(00400000), C(008F0000),
	 C(00920000), C(009D0000), C(00380000), C(00F50000),
	 C(00BC0000), C(00B60000), C(00DA0000), C(00210000),
	 C(00100000), C(00FF0000), C(00F30000), C(00D20000),
	 C(00CD0000), C(000C0000), C(00130000), C(00EC0000),
	 C(005F0000), C(00970000), C(00440000), C(00170000),
	 C(00C40000), C(00A70000), C(007E0000), C(003D0000),
	 C(00640000), C(005D0000), C(00190000), C(00730000),
	 C(00600000), C(00810000), C(004F0000), C(00DC0000),
	 C(00220000), C(002A0000), C(00900000), C(00880000),
	 C(00460000), C(00EE0000), C(00B80000), C(00140000),
	 C(00DE0000), C(005E0000), C(000B0000), C(00DB0000),
	 C(00E00000), C(00320000), C(003A0000), C(000A0000),
	 C(00490000), C(00060000), C(00240000), C(005C0000),
	 C(00C20000), C(00D30000), C(00AC0000), C(00620000),
	 C(00910000), C(00950000), C(00E40000), C(00790000),
	 C(00E70000), C(00C80000), C(00370000), C(006D0000),
	 C(008D0000), C(00D50000), C(004E0000), C(00A90000),
	 C(006C0000), C(00560000), C(00F40000), C(00EA0000),
	 C(00650000), C(007A0000), C(00AE0000), C(00080000),
	 C(00BA0000), C(00780000), C(00250000), C(002E0000),
	 C(001C0000), C(00A60000), C(00B40000), C(00C60000),
	 C(00E80000), C(00DD0000), C(00740000), C(001F0000),
	 C(004B0000), C(00BD0000), C(008B0000), C(008A0000),
	 C(00700000), C(003E0000), C(00B50000), C(00660000),
	 C(00480000), C(00030000), C(00F60000), C(000E0000),
	 C(00610000), C(00350000), C(00570000), C(00B90000),
	 C(00860000), C(00C10000), C(001D0000), C(009E0000),
	 C(00E10000), C(00F80000), C(00980000), C(00110000),
	 C(00690000), C(00D90000), C(008E0000), C(00940000),
	 C(009B0000), C(001E0000), C(00870000), C(00E90000),
	 C(00CE0000), C(00550000), C(00280000), C(00DF0000),
	 C(008C0000), C(00A10000), C(00890000), C(000D0000),
	 C(00BF0000), C(00E60000), C(00420000), C(00680000),
	 C(00410000), C(00990000), C(002D0000), C(000F0000),
	 C(00B00000), C(00540000), C(00BB0000), C(00160000)},

	{C(63000000), C(7C000000), C(77000000), C(7B000000),
	 C(F2000000), C(6B000000), C(6F000000), C(C5000000),
	 C(30000000), C(01000000), C(67000000), C(2B000000),
	 C(FE000000), C(D7000000), C(AB000000), C(76000000),
	 C(CA000000), C(82000000), C(C9000000), C(7D000000),
	 C(FA000000), C(59000000), C(47000000), C(F0000000),
	 C(AD000000), C(D4000000), C(A2000000), C(AF000000),
	 C(9C000000), C(A4000000), C(72000000), C(C0000000),
	 C(B7000000), C(FD000000), C(93000000), C(26000000),
	 C(36000000), C(3F000000), C(F7000000), C(CC000000),
	 C(34000000), C(A5000000), C(E5000000), C(F1000000),
	 C(71000000), C(D8000000), C(31000000), C(15000000),
	 C(04000000), C(C7000000), C(23000000), C(C3000000),
	 C(18000000), C(96000000), C(05000000), C(9A000000),
	 C(07000000), C(12000000), C(80000000), C(E2000000),
	 C(EB000000), C(27000000), C(B2000000), C(75000000),
	 C(09000000), C(83000000), C(2C000000), C(1A000000),
	 C(1B000000), C(6E000000), C(5A000000), C(A0000000),
	 C(52000000), C(3B000000), C(D6000000), C(B3000000),
	 C(29000000), C(E3000000), C(2F000000), C(84000000),
	 C(53000000), C(D1000000), C(00000000), C(ED000000),
	 C(20000000), C(FC000000), C(B1000000), C(5B000000),
	 C(6A000000), C(CB000000), C(BE000000), C(39000000),
	 C(4A000000), C(4C000000), C(58000000), C(CF000000),
	 C(D0000000), C(EF000000), C(AA000000), C(FB000000),
	 C(43000000), C(4D000000), C(33000000), C(85000000),
	 C(45000000), C(F9000000), C(02000000), C(7F000000),
	 C(50000000), C(3C000000), C(9F000000), C(A8000000),
	 C(51000000), C(A3000000), C(40000000), C(8F000000),
	 C(92000000), C(9D000000), C(38000000), C(F5000000),
	 C(BC000000), C(B6000000), C(DA000000), C(21000000),
	 C(10000000), C(FF000000), C(F3000000), C(D2000000),
	 C(CD000000), C(0C000000), C(13000000), C(EC000000),
	 C(5F000000), C(97000000), C(44000000), C(17000000),
	 C(C4000000), C(A7000000), C(7E000000), C(3D000000),
	 C(64000000), C(5D000000), C(19000000), C(73000000),
	 C(60000000), C(81000000), C(4F000000), C(DC000000),
	 C(22000000), C(2A000000), C(90000000), C(88000000),
	 C(46000000), C(EE000000), C(B8000000), C(14000000),
	 C(DE000000), C(5E000000), C(0B000000), C(DB000000),
	 C(E0000000), C(32000000), C(3A000000), C(0A000000),
	 C(49000000), C(06000000), C(24000000), C(5C000000),
	 C(C2000000), C(D3000000), C(AC000000), C(62000000),
	 C(91000000), C(95000000), C(E4000000), C(79000000),
	 C(E7000000), C(C8000000), C(37000000), C(6D000000),
	 C(8D000000), C(D5000000), C(4E000000), C(A9000000),
	 C(6C000000), C(56000000), C(F4000000), C(EA000000),
	 C(65000000), C(7A000000), C(AE000000), C(08000000),
	 C(BA000000), C(78000000), C(25000000), C(2E000000),
	 C(1C000000), C(A6000000), C(B4000000), C(C6000000),
	 C(E8000000), C(DD000000), C(74000000), C(1F000000),
	 C(4B000000), C(BD000000), C(8B000000), C(8A000000),
	 C(70000000), C(3E000000), C(B5000000), C(66000000),
	 C(48000000), C(03000000), C(F6000000), C(0E000000),
	 C(61000000), C(35000000), C(57000000), C(B9000000),
	 C(86000000), C(C1000000), C(1D000000), C(9E000000),
	 C(E1000000), C(F8000000), C(98000000), C(11000000),
	 C(69000000), C(D9000000), C(8E000000), C(94000000),
	 C(9B000000), C(1E000000), C(87000000), C(E9000000),
	 C(CE000000), C(55000000), C(28000000), C(DF000000),
	 C(8C000000), C(A1000000), C(89000000), C(0D000000),
	 C(BF000000), C(E6000000), C(42000000), C(68000000),
	 C(41000000), C(99000000), C(2D000000), C(0F000000),
	 C(B0000000), C(54000000), C(BB000000), C(16000000)}
};

static zuint32 const it[4][256] = {
	{C(50A7F451), C(5365417E), C(C3A4171A), C(965E273A),
	 C(CB6BAB3B), C(F1459D1F), C(AB58FAAC), C(9303E34B),
	 C(55FA3020), C(F66D76AD), C(9176CC88), C(254C02F5),
	 C(FCD7E54F), C(D7CB2AC5), C(80443526), C(8FA362B5),
	 C(495AB1DE), C(671BBA25), C(980EEA45), C(E1C0FE5D),
	 C(02752FC3), C(12F04C81), C(A397468D), C(C6F9D36B),
	 C(E75F8F03), C(959C9215), C(EB7A6DBF), C(DA595295),
	 C(2D83BED4), C(D3217458), C(2969E049), C(44C8C98E),
	 C(6A89C275), C(78798EF4), C(6B3E5899), C(DD71B927),
	 C(B64FE1BE), C(17AD88F0), C(66AC20C9), C(B43ACE7D),
	 C(184ADF63), C(82311AE5), C(60335197), C(457F5362),
	 C(E07764B1), C(84AE6BBB), C(1CA081FE), C(942B08F9),
	 C(58684870), C(19FD458F), C(876CDE94), C(B7F87B52),
	 C(23D373AB), C(E2024B72), C(578F1FE3), C(2AAB5566),
	 C(0728EBB2), C(03C2B52F), C(9A7BC586), C(A50837D3),
	 C(F2872830), C(B2A5BF23), C(BA6A0302), C(5C8216ED),
	 C(2B1CCF8A), C(92B479A7), C(F0F207F3), C(A1E2694E),
	 C(CDF4DA65), C(D5BE0506), C(1F6234D1), C(8AFEA6C4),
	 C(9D532E34), C(A055F3A2), C(32E18A05), C(75EBF6A4),
	 C(39EC830B), C(AAEF6040), C(069F715E), C(51106EBD),
	 C(F98A213E), C(3D06DD96), C(AE053EDD), C(46BDE64D),
	 C(B58D5491), C(055DC471), C(6FD40604), C(FF155060),
	 C(24FB9819), C(97E9BDD6), C(CC434089), C(779ED967),
	 C(BD42E8B0), C(888B8907), C(385B19E7), C(DBEEC879),
	 C(470A7CA1), C(E90F427C), C(C91E84F8), C(00000000),
	 C(83868009), C(48ED2B32), C(AC70111E), C(4E725A6C),
	 C(FBFF0EFD), C(5638850F), C(1ED5AE3D), C(27392D36),
	 C(64D90F0A), C(21A65C68), C(D1545B9B), C(3A2E3624),
	 C(B1670A0C), C(0FE75793), C(D296EEB4), C(9E919B1B),
	 C(4FC5C080), C(A220DC61), C(694B775A), C(161A121C),
	 C(0ABA93E2), C(E52AA0C0), C(43E0223C), C(1D171B12),
	 C(0B0D090E), C(ADC78BF2), C(B9A8B62D), C(C8A91E14),
	 C(8519F157), C(4C0775AF), C(BBDD99EE), C(FD607FA3),
	 C(9F2601F7), C(BCF5725C), C(C53B6644), C(347EFB5B),
	 C(7629438B), C(DCC623CB), C(68FCEDB6), C(63F1E4B8),
	 C(CADC31D7), C(10856342), C(40229713), C(2011C684),
	 C(7D244A85), C(F83DBBD2), C(1132F9AE), C(6DA129C7),
	 C(4B2F9E1D), C(F330B2DC), C(EC52860D), C(D0E3C177),
	 C(6C16B32B), C(99B970A9), C(FA489411), C(2264E947),
	 C(C48CFCA8), C(1A3FF0A0), C(D82C7D56), C(EF903322),
	 C(C74E4987), C(C1D138D9), C(FEA2CA8C), C(360BD498),
	 C(CF81F5A6), C(28DE7AA5), C(268EB7DA), C(A4BFAD3F),
	 C(E49D3A2C), C(0D927850), C(9BCC5F6A), C(62467E54),
	 C(C2138DF6), C(E8B8D890), C(5EF7392E), C(F5AFC382),
	 C(BE805D9F), C(7C93D069), C(A92DD56F), C(B31225CF),
	 C(3B99ACC8), C(A77D1810), C(6E639CE8), C(7BBB3BDB),
	 C(097826CD), C(F418596E), C(01B79AEC), C(A89A4F83),
	 C(656E95E6), C(7EE6FFAA), C(08CFBC21), C(E6E815EF),
	 C(D99BE7BA), C(CE366F4A), C(D4099FEA), C(D67CB029),
	 C(AFB2A431), C(31233F2A), C(3094A5C6), C(C066A235),
	 C(37BC4E74), C(A6CA82FC), C(B0D090E0), C(15D8A733),
	 C(4A9804F1), C(F7DAEC41), C(0E50CD7F), C(2FF69117),
	 C(8DD64D76), C(4DB0EF43), C(544DAACC), C(DF0496E4),
	 C(E3B5D19E), C(1B886A4C), C(B81F2CC1), C(7F516546),
	 C(04EA5E9D), C(5D358C01), C(737487FA), C(2E410BFB),
	 C(5A1D67B3), C(52D2DB92), C(335610E9), C(1347D66D),
	 C(8C61D79A), C(7A0CA137), C(8E14F859), C(893C13EB),
	 C(EE27A9CE), C(35C961B7), C(EDE51CE1), C(3CB1477A),
	 C(59DFD29C), C(3F73F255), C(79CE1418), C(BF37C773),
	 C(EACDF753), C(5BAAFD5F), C(146F3DDF), C(86DB4478),
	 C(81F3AFCA), C(3EC468B9), C(2C342438), C(5F40A3C2),
	 C(72C31D16), C(0C25E2BC), C(8B493C28), C(41950DFF),
	 C(7101A839), C(DEB30C08), C(9CE4B4D8), C(90C15664),
	 C(6184CB7B), C(70B632D5), C(745C6C48), C(4257B8D0)},

	{C(A7F45150), C(65417E53), C(A4171AC3), C(5E273A96),
	 C(6BAB3BCB), C(459D1FF1), C(58FAACAB), C(03E34B93),
	 C(FA302055), C(6D76ADF6), C(76CC8891), C(4C02F525),
	 C(D7E54FFC), C(CB2AC5D7), C(44352680), C(A362B58F),
	 C(5AB1DE49), C(1BBA2567), C(0EEA4598), C(C0FE5DE1),
	 C(752FC302), C(F04C8112), C(97468DA3), C(F9D36BC6),
	 C(5F8F03E7), C(9C921595), C(7A6DBFEB), C(595295DA),
	 C(83BED42D), C(217458D3), C(69E04929), C(C8C98E44),
	 C(89C2756A), C(798EF478), C(3E58996B), C(71B927DD),
	 C(4FE1BEB6), C(AD88F017), C(AC20C966), C(3ACE7DB4),
	 C(4ADF6318), C(311AE582), C(33519760), C(7F536245),
	 C(7764B1E0), C(AE6BBB84), C(A081FE1C), C(2B08F994),
	 C(68487058), C(FD458F19), C(6CDE9487), C(F87B52B7),
	 C(D373AB23), C(024B72E2), C(8F1FE357), C(AB55662A),
	 C(28EBB207), C(C2B52F03), C(7BC5869A), C(0837D3A5),
	 C(872830F2), C(A5BF23B2), C(6A0302BA), C(8216ED5C),
	 C(1CCF8A2B), C(B479A792), C(F207F3F0), C(E2694EA1),
	 C(F4DA65CD), C(BE0506D5), C(6234D11F), C(FEA6C48A),
	 C(532E349D), C(55F3A2A0), C(E18A0532), C(EBF6A475),
	 C(EC830B39), C(EF6040AA), C(9F715E06), C(106EBD51),
	 C(8A213EF9), C(06DD963D), C(053EDDAE), C(BDE64D46),
	 C(8D5491B5), C(5DC47105), C(D406046F), C(155060FF),
	 C(FB981924), C(E9BDD697), C(434089CC), C(9ED96777),
	 C(42E8B0BD), C(8B890788), C(5B19E738), C(EEC879DB),
	 C(0A7CA147), C(0F427CE9), C(1E84F8C9), C(00000000),
	 C(86800983), C(ED2B3248), C(70111EAC), C(725A6C4E),
	 C(FF0EFDFB), C(38850F56), C(D5AE3D1E), C(392D3627),
	 C(D90F0A64), C(A65C6821), C(545B9BD1), C(2E36243A),
	 C(670A0CB1), C(E757930F), C(96EEB4D2), C(919B1B9E),
	 C(C5C0804F), C(20DC61A2), C(4B775A69), C(1A121C16),
	 C(BA93E20A), C(2AA0C0E5), C(E0223C43), C(171B121D),
	 C(0D090E0B), C(C78BF2AD), C(A8B62DB9), C(A91E14C8),
	 C(19F15785), C(0775AF4C), C(DD99EEBB), C(607FA3FD),
	 C(2601F79F), C(F5725CBC), C(3B6644C5), C(7EFB5B34),
	 C(29438B76), C(C623CBDC), C(FCEDB668), C(F1E4B863),
	 C(DC31D7CA), C(85634210), C(22971340), C(11C68420),
	 C(244A857D), C(3DBBD2F8), C(32F9AE11), C(A129C76D),
	 C(2F9E1D4B), C(30B2DCF3), C(52860DEC), C(E3C177D0),
	 C(16B32B6C), C(B970A999), C(489411FA), C(64E94722),
	 C(8CFCA8C4), C(3FF0A01A), C(2C7D56D8), C(903322EF),
	 C(4E4987C7), C(D138D9C1), C(A2CA8CFE), C(0BD49836),
	 C(81F5A6CF), C(DE7AA528), C(8EB7DA26), C(BFAD3FA4),
	 C(9D3A2CE4), C(9278500D), C(CC5F6A9B), C(467E5462),
	 C(138DF6C2), C(B8D890E8), C(F7392E5E), C(AFC382F5),
	 C(805D9FBE), C(93D0697C), C(2DD56FA9), C(1225CFB3),
	 C(99ACC83B), C(7D1810A7), C(639CE86E), C(BB3BDB7B),
	 C(7826CD09), C(18596EF4), C(B79AEC01), C(9A4F83A8),
	 C(6E95E665), C(E6FFAA7E), C(CFBC2108), C(E815EFE6),
	 C(9BE7BAD9), C(366F4ACE), C(099FEAD4), C(7CB029D6),
	 C(B2A431AF), C(233F2A31), C(94A5C630), C(66A235C0),
	 C(BC4E7437), C(CA82FCA6), C(D090E0B0), C(D8A73315),
	 C(9804F14A), C(DAEC41F7), C(50CD7F0E), C(F691172F),
	 C(D64D768D), C(B0EF434D), C(4DAACC54), C(0496E4DF),
	 C(B5D19EE3), C(886A4C1B), C(1F2CC1B8), C(5165467F),
	 C(EA5E9D04), C(358C015D), C(7487FA73), C(410BFB2E),
	 C(1D67B35A), C(D2DB9252), C(5610E933), C(47D66D13),
	 C(61D79A8C), C(0CA1377A), C(14F8598E), C(3C13EB89),
	 C(27A9CEEE), C(C961B735), C(E51CE1ED), C(B1477A3C),
	 C(DFD29C59), C(73F2553F), C(CE141879), C(37C773BF),
	 C(CDF753EA), C(AAFD5F5B), C(6F3DDF14), C(DB447886),
	 C(F3AFCA81), C(C468B93E), C(3424382C), C(40A3C25F),
	 C(C31D1672), C(25E2BC0C), C(493C288B), C(950DFF41),
	 C(01A83971), C(B30C08DE), C(E4B4D89C), C(C1566490),
	 C(84CB7B61), C(B632D570), C(5C6C4874), C(57B8D042)},

	{C(F45150A7), C(417E5365), C(171AC3A4), C(273A965E),
	 C(AB3BCB6B), C(9D1FF145), C(FAACAB58), C(E34B9303),
	 C(302055FA), C(76ADF66D), C(CC889176), C(02F5254C),
	 C(E54FFCD7), C(2AC5D7CB), C(35268044), C(62B58FA3),
	 C(B1DE495A), C(BA25671B), C(EA45980E), C(FE5DE1C0),
	 C(2FC30275), C(4C8112F0), C(468DA397), C(D36BC6F9),
	 C(8F03E75F), C(9215959C), C(6DBFEB7A), C(5295DA59),
	 C(BED42D83), C(7458D321), C(E0492969), C(C98E44C8),
	 C(C2756A89), C(8EF47879), C(58996B3E), C(B927DD71),
	 C(E1BEB64F), C(88F017AD), C(20C966AC), C(CE7DB43A),
	 C(DF63184A), C(1AE58231), C(51976033), C(5362457F),
	 C(64B1E077), C(6BBB84AE), C(81FE1CA0), C(08F9942B),
	 C(48705868), C(458F19FD), C(DE94876C), C(7B52B7F8),
	 C(73AB23D3), C(4B72E202), C(1FE3578F), C(55662AAB),
	 C(EBB20728), C(B52F03C2), C(C5869A7B), C(37D3A508),
	 C(2830F287), C(BF23B2A5), C(0302BA6A), C(16ED5C82),
	 C(CF8A2B1C), C(79A792B4), C(07F3F0F2), C(694EA1E2),
	 C(DA65CDF4), C(0506D5BE), C(34D11F62), C(A6C48AFE),
	 C(2E349D53), C(F3A2A055), C(8A0532E1), C(F6A475EB),
	 C(830B39EC), C(6040AAEF), C(715E069F), C(6EBD5110),
	 C(213EF98A), C(DD963D06), C(3EDDAE05), C(E64D46BD),
	 C(5491B58D), C(C471055D), C(06046FD4), C(5060FF15),
	 C(981924FB), C(BDD697E9), C(4089CC43), C(D967779E),
	 C(E8B0BD42), C(8907888B), C(19E7385B), C(C879DBEE),
	 C(7CA1470A), C(427CE90F), C(84F8C91E), C(00000000),
	 C(80098386), C(2B3248ED), C(111EAC70), C(5A6C4E72),
	 C(0EFDFBFF), C(850F5638), C(AE3D1ED5), C(2D362739),
	 C(0F0A64D9), C(5C6821A6), C(5B9BD154), C(36243A2E),
	 C(0A0CB167), C(57930FE7), C(EEB4D296), C(9B1B9E91),
	 C(C0804FC5), C(DC61A220), C(775A694B), C(121C161A),
	 C(93E20ABA), C(A0C0E52A), C(223C43E0), C(1B121D17),
	 C(090E0B0D), C(8BF2ADC7), C(B62DB9A8), C(1E14C8A9),
	 C(F1578519), C(75AF4C07), C(99EEBBDD), C(7FA3FD60),
	 C(01F79F26), C(725CBCF5), C(6644C53B), C(FB5B347E),
	 C(438B7629), C(23CBDCC6), C(EDB668FC), C(E4B863F1),
	 C(31D7CADC), C(63421085), C(97134022), C(C6842011),
	 C(4A857D24), C(BBD2F83D), C(F9AE1132), C(29C76DA1),
	 C(9E1D4B2F), C(B2DCF330), C(860DEC52), C(C177D0E3),
	 C(B32B6C16), C(70A999B9), C(9411FA48), C(E9472264),
	 C(FCA8C48C), C(F0A01A3F), C(7D56D82C), C(3322EF90),
	 C(4987C74E), C(38D9C1D1), C(CA8CFEA2), C(D498360B),
	 C(F5A6CF81), C(7AA528DE), C(B7DA268E), C(AD3FA4BF),
	 C(3A2CE49D), C(78500D92), C(5F6A9BCC), C(7E546246),
	 C(8DF6C213), C(D890E8B8), C(392E5EF7), C(C382F5AF),
	 C(5D9FBE80), C(D0697C93), C(D56FA92D), C(25CFB312),
	 C(ACC83B99), C(1810A77D), C(9CE86E63), C(3BDB7BBB),
	 C(26CD0978), C(596EF418), C(9AEC01B7), C(4F83A89A),
	 C(95E6656E), C(FFAA7EE6), C(BC2108CF), C(15EFE6E8),
	 C(E7BAD99B), C(6F4ACE36), C(9FEAD409), C(B029D67C),
	 C(A431AFB2), C(3F2A3123), C(A5C63094), C(A235C066),
	 C(4E7437BC), C(82FCA6CA), C(90E0B0D0), C(A73315D8),
	 C(04F14A98), C(EC41F7DA), C(CD7F0E50), C(91172FF6),
	 C(4D768DD6), C(EF434DB0), C(AACC544D), C(96E4DF04),
	 C(D19EE3B5), C(6A4C1B88), C(2CC1B81F), C(65467F51),
	 C(5E9D04EA), C(8C015D35), C(87FA7374), C(0BFB2E41),
	 C(67B35A1D), C(DB9252D2), C(10E93356), C(D66D1347),
	 C(D79A8C61), C(A1377A0C), C(F8598E14), C(13EB893C),
	 C(A9CEEE27), C(61B735C9), C(1CE1EDE5), C(477A3CB1),
	 C(D29C59DF), C(F2553F73), C(141879CE), C(C773BF37),
	 C(F753EACD), C(FD5F5BAA), C(3DDF146F), C(447886DB),
	 C(AFCA81F3), C(68B93EC4), C(24382C34), C(A3C25F40),
	 C(1D1672C3), C(E2BC0C25), C(3C288B49), C(0DFF4195),
	 C(A8397101), C(0C08DEB3), C(B4D89CE4), C(566490C1),
	 C(CB7B6184), C(32D570B6), C(6C48745C), C(B8D04257)},

	{C(5150A7F4), C(7E536541), C(1AC3A417), C(3A965E27),
	 C(3BCB6BAB), C(1FF1459D), C(ACAB58FA), C(4B9303E3),
	 C(2055FA30), C(ADF66D76), C(889176CC), C(F5254C02),
	 C(4FFCD7E5), C(C5D7CB2A), C(26804435), C(B58FA362),
	 C(DE495AB1), C(25671BBA), C(45980EEA), C(5DE1C0FE),
	 C(C302752F), C(8112F04C), C(8DA39746), C(6BC6F9D3),
	 C(03E75F8F), C(15959C92), C(BFEB7A6D), C(95DA5952),
	 C(D42D83BE), C(58D32174), C(492969E0), C(8E44C8C9),
	 C(756A89C2), C(F478798E), C(996B3E58), C(27DD71B9),
	 C(BEB64FE1), C(F017AD88), C(C966AC20), C(7DB43ACE),
	 C(63184ADF), C(E582311A), C(97603351), C(62457F53),
	 C(B1E07764), C(BB84AE6B), C(FE1CA081), C(F9942B08),
	 C(70586848), C(8F19FD45), C(94876CDE), C(52B7F87B),
	 C(AB23D373), C(72E2024B), C(E3578F1F), C(662AAB55),
	 C(B20728EB), C(2F03C2B5), C(869A7BC5), C(D3A50837),
	 C(30F28728), C(23B2A5BF), C(02BA6A03), C(ED5C8216),
	 C(8A2B1CCF), C(A792B479), C(F3F0F207), C(4EA1E269),
	 C(65CDF4DA), C(06D5BE05), C(D11F6234), C(C48AFEA6),
	 C(349D532E), C(A2A055F3), C(0532E18A), C(A475EBF6),
	 C(0B39EC83), C(40AAEF60), C(5E069F71), C(BD51106E),
	 C(3EF98A21), C(963D06DD), C(DDAE053E), C(4D46BDE6),
	 C(91B58D54), C(71055DC4), C(046FD406), C(60FF1550),
	 C(1924FB98), C(D697E9BD), C(89CC4340), C(67779ED9),
	 C(B0BD42E8), C(07888B89), C(E7385B19), C(79DBEEC8),
	 C(A1470A7C), C(7CE90F42), C(F8C91E84), C(00000000),
	 C(09838680), C(3248ED2B), C(1EAC7011), C(6C4E725A),
	 C(FDFBFF0E), C(0F563885), C(3D1ED5AE), C(3627392D),
	 C(0A64D90F), C(6821A65C), C(9BD1545B), C(243A2E36),
	 C(0CB1670A), C(930FE757), C(B4D296EE), C(1B9E919B),
	 C(804FC5C0), C(61A220DC), C(5A694B77), C(1C161A12),
	 C(E20ABA93), C(C0E52AA0), C(3C43E022), C(121D171B),
	 C(0E0B0D09), C(F2ADC78B), C(2DB9A8B6), C(14C8A91E),
	 C(578519F1), C(AF4C0775), C(EEBBDD99), C(A3FD607F),
	 C(F79F2601), C(5CBCF572), C(44C53B66), C(5B347EFB),
	 C(8B762943), C(CBDCC623), C(B668FCED), C(B863F1E4),
	 C(D7CADC31), C(42108563), C(13402297), C(842011C6),
	 C(857D244A), C(D2F83DBB), C(AE1132F9), C(C76DA129),
	 C(1D4B2F9E), C(DCF330B2), C(0DEC5286), C(77D0E3C1),
	 C(2B6C16B3), C(A999B970), C(11FA4894), C(472264E9),
	 C(A8C48CFC), C(A01A3FF0), C(56D82C7D), C(22EF9033),
	 C(87C74E49), C(D9C1D138), C(8CFEA2CA), C(98360BD4),
	 C(A6CF81F5), C(A528DE7A), C(DA268EB7), C(3FA4BFAD),
	 C(2CE49D3A), C(500D9278), C(6A9BCC5F), C(5462467E),
	 C(F6C2138D), C(90E8B8D8), C(2E5EF739), C(82F5AFC3),
	 C(9FBE805D), C(697C93D0), C(6FA92DD5), C(CFB31225),
	 C(C83B99AC), C(10A77D18), C(E86E639C), C(DB7BBB3B),
	 C(CD097826), C(6EF41859), C(EC01B79A), C(83A89A4F),
	 C(E6656E95), C(AA7EE6FF), C(2108CFBC), C(EFE6E815),
	 C(BAD99BE7), C(4ACE366F), C(EAD4099F), C(29D67CB0),
	 C(31AFB2A4), C(2A31233F), C(C63094A5), C(35C066A2),
	 C(7437BC4E), C(FCA6CA82), C(E0B0D090), C(3315D8A7),
	 C(F14A9804), C(41F7DAEC), C(7F0E50CD), C(172FF691),
	 C(768DD64D), C(434DB0EF), C(CC544DAA), C(E4DF0496),
	 C(9EE3B5D1), C(4C1B886A), C(C1B81F2C), C(467F5165),
	 C(9D04EA5E), C(015D358C), C(FA737487), C(FB2E410B),
	 C(B35A1D67), C(9252D2DB), C(E9335610), C(6D1347D6),
	 C(9A8C61D7), C(377A0CA1), C(598E14F8), C(EB893C13),
	 C(CEEE27A9), C(B735C961), C(E1EDE51C), C(7A3CB147),
	 C(9C59DFD2), C(553F73F2), C(1879CE14), C(73BF37C7),
	 C(53EACDF7), C(5F5BAAFD), C(DF146F3D), C(7886DB44),
	 C(CA81F3AF), C(B93EC468), C(382C3424), C(C25F40A3),
	 C(1672C31D), C(BC0C25E2), C(288B493C), C(FF41950D),
	 C(397101A8), C(08DEB30C), C(D89CE4B4), C(6490C156),
	 C(7B6184CB), C(D570B632), C(48745C6C), C(D04257B8)}
};

static zuint32 const il[4][256] = {
	{C(00000052), C(00000009), C(0000006A), C(000000D5),
	 C(00000030), C(00000036), C(000000A5), C(00000038),
	 C(000000BF), C(00000040), C(000000A3), C(0000009E),
	 C(00000081), C(000000F3), C(000000D7), C(000000FB),
	 C(0000007C), C(000000E3), C(00000039), C(00000082),
	 C(0000009B), C(0000002F), C(000000FF), C(00000087),
	 C(00000034), C(0000008E), C(00000043), C(00000044),
	 C(000000C4), C(000000DE), C(000000E9), C(000000CB),
	 C(00000054), C(0000007B), C(00000094), C(00000032),
	 C(000000A6), C(000000C2), C(00000023), C(0000003D),
	 C(000000EE), C(0000004C), C(00000095), C(0000000B),
	 C(00000042), C(000000FA), C(000000C3), C(0000004E),
	 C(00000008), C(0000002E), C(000000A1), C(00000066),
	 C(00000028), C(000000D9), C(00000024), C(000000B2),
	 C(00000076), C(0000005B), C(000000A2), C(00000049),
	 C(0000006D), C(0000008B), C(000000D1), C(00000025),
	 C(00000072), C(000000F8), C(000000F6), C(00000064),
	 C(00000086), C(00000068), C(00000098), C(00000016),
	 C(000000D4), C(000000A4), C(0000005C), C(000000CC),
	 C(0000005D), C(00000065), C(000000B6), C(00000092),
	 C(0000006C), C(00000070), C(00000048), C(00000050),
	 C(000000FD), C(000000ED), C(000000B9), C(000000DA),
	 C(0000005E), C(00000015), C(00000046), C(00000057),
	 C(000000A7), C(0000008D), C(0000009D), C(00000084),
	 C(00000090), C(000000D8), C(000000AB), C(00000000),
	 C(0000008C), C(000000BC), C(000000D3), C(0000000A),
	 C(000000F7), C(000000E4), C(00000058), C(00000005),
	 C(000000B8), C(000000B3), C(00000045), C(00000006),
	 C(000000D0), C(0000002C), C(0000001E), C(0000008F),
	 C(000000CA), C(0000003F), C(0000000F), C(00000002),
	 C(000000C1), C(000000AF), C(000000BD), C(00000003),
	 C(00000001), C(00000013), C(0000008A), C(0000006B),
	 C(0000003A), C(00000091), C(00000011), C(00000041),
	 C(0000004F), C(00000067), C(000000DC), C(000000EA),
	 C(00000097), C(000000F2), C(000000CF), C(000000CE),
	 C(000000F0), C(000000B4), C(000000E6), C(00000073),
	 C(00000096), C(000000AC), C(00000074), C(00000022),
	 C(000000E7), C(000000AD), C(00000035), C(00000085),
	 C(000000E2), C(000000F9), C(00000037), C(000000E8),
	 C(0000001C), C(00000075), C(000000DF), C(0000006E),
	 C(00000047), C(000000F1), C(0000001A), C(00000071),
	 C(0000001D), C(00000029), C(000000C5), C(00000089),
	 C(0000006F), C(000000B7), C(00000062), C(0000000E),
	 C(000000AA), C(00000018), C(000000BE), C(0000001B),
	 C(000000FC), C(00000056), C(0000003E), C(0000004B),
	 C(000000C6), C(000000D2), C(00000079), C(00000020),
	 C(0000009A), C(000000DB), C(000000C0), C(000000FE),
	 C(00000078), C(000000CD), C(0000005A), C(000000F4),
	 C(0000001F), C(000000DD), C(000000A8), C(00000033),
	 C(00000088), C(00000007), C(000000C7), C(00000031),
	 C(000000B1), C(00000012), C(00000010), C(00000059),
	 C(00000027), C(00000080), C(000000EC), C(0000005F),
	 C(00000060), C(00000051), C(0000007F), C(000000A9),
	 C(00000019), C(000000B5), C(0000004A), C(0000000D),
	 C(0000002D), C(000000E5), C(0000007A), C(0000009F),
	 C(00000093), C(000000C9), C(0000009C), C(000000EF),
	 C(000000A0), C(000000E0), C(0000003B), C(0000004D),
	 C(000000AE), C(0000002A), C(000000F5), C(000000B0),
	 C(000000C8), C(000000EB), C(000000BB), C(0000003C),
	 C(00000083), C(00000053), C(00000099), C(00000061),
	 C(00000017), C(0000002B), C(00000004), C(0000007E),
	 C(000000BA), C(00000077), C(000000D6), C(00000026),
	 C(000000E1), C(00000069), C(00000014), C(00000063),
	 C(00000055), C(00000021), C(0000000C), C(0000007D)},

	{C(00005200), C(00000900), C(00006A00), C(0000D500),
	 C(00003000), C(00003600), C(0000A500), C(00003800),
	 C(0000BF00), C(00004000), C(0000A300), C(00009E00),
	 C(00008100), C(0000F300), C(0000D700), C(0000FB00),
	 C(00007C00), C(0000E300), C(00003900), C(00008200),
	 C(00009B00), C(00002F00), C(0000FF00), C(00008700),
	 C(00003400), C(00008E00), C(00004300), C(00004400),
	 C(0000C400), C(0000DE00), C(0000E900), C(0000CB00),
	 C(00005400), C(00007B00), C(00009400), C(00003200),
	 C(0000A600), C(0000C200), C(00002300), C(00003D00),
	 C(0000EE00), C(00004C00), C(00009500), C(00000B00),
	 C(00004200), C(0000FA00), C(0000C300), C(00004E00),
	 C(00000800), C(00002E00), C(0000A100), C(00006600),
	 C(00002800), C(0000D900), C(00002400), C(0000B200),
	 C(00007600), C(00005B00), C(0000A200), C(00004900),
	 C(00006D00), C(00008B00), C(0000D100), C(00002500),
	 C(00007200), C(0000F800), C(0000F600), C(00006400),
	 C(00008600), C(00006800), C(00009800), C(00001600),
	 C(0000D400), C(0000A400), C(00005C00), C(0000CC00),
	 C(00005D00), C(00006500), C(0000B600), C(00009200),
	 C(00006C00), C(00007000), C(00004800), C(00005000),
	 C(0000FD00), C(0000ED00), C(0000B900), C(0000DA00),
	 C(00005E00), C(00001500), C(00004600), C(00005700),
	 C(0000A700), C(00008D00), C(00009D00), C(00008400),
	 C(00009000), C(0000D800), C(0000AB00), C(00000000),
	 C(00008C00), C(0000BC00), C(0000D300), C(00000A00),
	 C(0000F700), C(0000E400), C(00005800), C(00000500),
	 C(0000B800), C(0000B300), C(00004500), C(00000600),
	 C(0000D000), C(00002C00), C(00001E00), C(00008F00),
	 C(0000CA00), C(00003F00), C(00000F00), C(00000200),
	 C(0000C100), C(0000AF00), C(0000BD00), C(00000300),
	 C(00000100), C(00001300), C(00008A00), C(00006B00),
	 C(00003A00), C(00009100), C(00001100), C(00004100),
	 C(00004F00), C(00006700), C(0000DC00), C(0000EA00),
	 C(00009700), C(0000F200), C(0000CF00), C(0000CE00),
	 C(0000F000), C(0000B400), C(0000E600), C(00007300),
	 C(00009600), C(0000AC00), C(00007400), C(00002200),
	 C(0000E700), C(0000AD00), C(00003500), C(00008500),
	 C(0000E200), C(0000F900), C(00003700), C(0000E800),
	 C(00001C00), C(00007500), C(0000DF00), C(00006E00),
	 C(00004700), C(0000F100), C(00001A00), C(00007100),
	 C(00001D00), C(00002900), C(0000C500), C(00008900),
	 C(00006F00), C(0000B700), C(00006200), C(00000E00),
	 C(0000AA00), C(00001800), C(0000BE00), C(00001B00),
	 C(0000FC00), C(00005600), C(00003E00), C(00004B00),
	 C(0000C600), C(0000D200), C(00007900), C(00002000),
	 C(00009A00), C(0000DB00), C(0000C000), C(0000FE00),
	 C(00007800), C(0000CD00), C(00005A00), C(0000F400),
	 C(00001F00), C(0000DD00), C(0000A800), C(00003300),
	 C(00008800), C(00000700), C(0000C700), C(00003100),
	 C(0000B100), C(00001200), C(00001000), C(00005900),
	 C(00002700), C(00008000), C(0000EC00), C(00005F00),
	 C(00006000), C(00005100), C(00007F00), C(0000A900),
	 C(00001900), C(0000B500), C(00004A00), C(00000D00),
	 C(00002D00), C(0000E500), C(00007A00), C(00009F00),
	 C(00009300), C(0000C900), C(00009C00), C(0000EF00),
	 C(0000A000), C(0000E000), C(00003B00), C(00004D00),
	 C(0000AE00), C(00002A00), C(0000F500), C(0000B000),
	 C(0000C800), C(0000EB00), C(0000BB00), C(00003C00),
	 C(00008300), C(00005300), C(00009900), C(00006100),
	 C(00001700), C(00002B00), C(00000400), C(00007E00),
	 C(0000BA00), C(00007700), C(0000D600), C(00002600),
	 C(0000E100), C(00006900), C(00001400), C(00006300),
	 C(00005500), C(00002100), C(00000C00), C(00007D00)},

	{C(00520000), C(00090000), C(006A0000), C(00D50000),
	 C(00300000), C(00360000), C(00A50000), C(00380000),
	 C(00BF0000), C(00400000), C(00A30000), C(009E0000),
	 C(00810000), C(00F30000), C(00D70000), C(00FB0000),
	 C(007C0000), C(00E30000), C(00390000), C(00820000),
	 C(009B0000), C(002F0000), C(00FF0000), C(00870000),
	 C(00340000), C(008E0000), C(00430000), C(00440000),
	 C(00C40000), C(00DE0000), C(00E90000), C(00CB0000),
	 C(00540000), C(007B0000), C(00940000), C(00320000),
	 C(00A60000), C(00C20000), C(00230000), C(003D0000),
	 C(00EE0000), C(004C0000), C(00950000), C(000B0000),
	 C(00420000), C(00FA0000), C(00C30000), C(004E0000),
	 C(00080000), C(002E0000), C(00A10000), C(00660000),
	 C(00280000), C(00D90000), C(00240000), C(00B20000),
	 C(00760000), C(005B0000), C(00A20000), C(00490000),
	 C(006D0000), C(008B0000), C(00D10000), C(00250000),
	 C(00720000), C(00F80000), C(00F60000), C(00640000),
	 C(00860000), C(00680000), C(00980000), C(00160000),
	 C(00D40000), C(00A40000), C(005C0000), C(00CC0000),
	 C(005D0000), C(00650000), C(00B60000), C(00920000),
	 C(006C0000), C(00700000), C(00480000), C(00500000),
	 C(00FD0000), C(00ED0000), C(00B90000), C(00DA0000),
	 C(005E0000), C(00150000), C(00460000), C(00570000),
	 C(00A70000), C(008D0000), C(009D0000), C(00840000),
	 C(00900000), C(00D80000), C(00AB0000), C(00000000),
	 C(008C0000), C(00BC0000), C(00D30000), C(000A0000),
	 C(00F70000), C(00E40000), C(00580000), C(00050000),
	 C(00B80000), C(00B30000), C(00450000), C(00060000),
	 C(00D00000), C(002C0000), C(001E0000), C(008F0000),
	 C(00CA0000), C(003F0000), C(000F0000), C(00020000),
	 C(00C10000), C(00AF0000), C(00BD0000), C(00030000),
	 C(00010000), C(00130000), C(008A0000), C(006B0000),
	 C(003A0000), C(00910000), C(00110000), C(00410000),
	 C(004F0000), C(00670000), C(00DC0000), C(00EA0000),
	 C(00970000), C(00F20000), C(00CF0000), C(00CE0000),
	 C(00F00000), C(00B40000), C(00E60000), C(00730000),
	 C(00960000), C(00AC0000), C(00740000), C(00220000),
	 C(00E70000), C(00AD0000), C(00350000), C(00850000),
	 C(00E20000), C(00F90000), C(00370000), C(00E80000),
	 C(001C0000), C(00750000), C(00DF0000), C(006E0000),
	 C(00470000), C(00F10000), C(001A0000), C(00710000),
	 C(001D0000), C(00290000), C(00C50000), C(00890000),
	 C(006F0000), C(00B70000), C(00620000), C(000E0000),
	 C(00AA0000), C(00180000), C(00BE0000), C(001B0000),
	 C(00FC0000), C(00560000), C(003E0000), C(004B0000),
	 C(00C60000), C(00D20000), C(00790000), C(00200000),
	 C(009A0000), C(00DB0000), C(00C00000), C(00FE0000),
	 C(00780000), C(00CD0000), C(005A0000), C(00F40000),
	 C(001F0000), C(00DD0000), C(00A80000), C(00330000),
	 C(00880000), C(00070000), C(00C70000), C(00310000),
	 C(00B10000), C(00120000), C(00100000), C(00590000),
	 C(00270000), C(00800000), C(00EC0000), C(005F0000),
	 C(00600000), C(00510000), C(007F0000), C(00A90000),
	 C(00190000), C(00B50000), C(004A0000), C(000D0000),
	 C(002D0000), C(00E50000), C(007A0000), C(009F0000),
	 C(00930000), C(00C90000), C(009C0000), C(00EF0000),
	 C(00A00000), C(00E00000), C(003B0000), C(004D0000),
	 C(00AE0000), C(002A0000), C(00F50000), C(00B00000),
	 C(00C80000), C(00EB0000), C(00BB0000), C(003C0000),
	 C(00830000), C(00530000), C(00990000), C(00610000),
	 C(00170000), C(002B0000), C(00040000), C(007E0000),
	 C(00BA0000), C(00770000), C(00D60000), C(00260000),
	 C(00E10000), C(00690000), C(00140000), C(00630000),
	 C(00550000), C(00210000), C(000C0000), C(007D0000)},

	{C(52000000), C(09000000), C(6A000000), C(D5000000),
	 C(30000000), C(36000000), C(A5000000), C(38000000),
	 C(BF000000), C(40000000), C(A3000000), C(9E000000),
	 C(81000000), C(F3000000), C(D7000000), C(FB000000),
	 C(7C000000), C(E3000000), C(39000000), C(82000000),
	 C(9B000000), C(2F000000), C(FF000000), C(87000000),
	 C(34000000), C(8E000000), C(43000000), C(44000000),
	 C(C4000000), C(DE000000), C(E9000000), C(CB000000),
	 C(54000000), C(7B000000), C(94000000), C(32000000),
	 C(A6000000), C(C2000000), C(23000000), C(3D000000),
	 C(EE000000), C(4C000000), C(95000000), C(0B000000),
	 C(42000000), C(FA000000), C(C3000000), C(4E000000),
	 C(08000000), C(2E000000), C(A1000000), C(66000000),
	 C(28000000), C(D9000000), C(24000000), C(B2000000),
	 C(76000000), C(5B000000), C(A2000000), C(49000000),
	 C(6D000000), C(8B000000), C(D1000000), C(25000000),
	 C(72000000), C(F8000000), C(F6000000), C(64000000),
	 C(86000000), C(68000000), C(98000000), C(16000000),
	 C(D4000000), C(A4000000), C(5C000000), C(CC000000),
	 C(5D000000), C(65000000), C(B6000000), C(92000000),
	 C(6C000000), C(70000000), C(48000000), C(50000000),
	 C(FD000000), C(ED000000), C(B9000000), C(DA000000),
	 C(5E000000), C(15000000), C(46000000), C(57000000),
	 C(A7000000), C(8D000000), C(9D000000), C(84000000),
	 C(90000000), C(D8000000), C(AB000000), C(00000000),
	 C(8C000000), C(BC000000), C(D3000000), C(0A000000),
	 C(F7000000), C(E4000000), C(58000000), C(05000000),
	 C(B8000000), C(B3000000), C(45000000), C(06000000),
	 C(D0000000), C(2C000000), C(1E000000), C(8F000000),
	 C(CA000000), C(3F000000), C(0F000000), C(02000000),
	 C(C1000000), C(AF000000), C(BD000000), C(03000000),
	 C(01000000), C(13000000), C(8A000000), C(6B000000),
	 C(3A000000), C(91000000), C(11000000), C(41000000),
	 C(4F000000), C(67000000), C(DC000000), C(EA000000),
	 C(97000000), C(F2000000), C(CF000000), C(CE000000),
	 C(F0000000), C(B4000000), C(E6000000), C(73000000),
	 C(96000000), C(AC000000), C(74000000), C(22000000),
	 C(E7000000), C(AD000000), C(35000000), C(85000000),
	 C(E2000000), C(F9000000), C(37000000), C(E8000000),
	 C(1C000000), C(75000000), C(DF000000), C(6E000000),
	 C(47000000), C(F1000000), C(1A000000), C(71000000),
	 C(1D000000), C(29000000), C(C5000000), C(89000000),
	 C(6F000000), C(B7000000), C(62000000), C(0E000000),
	 C(AA000000), C(18000000), C(BE000000), C(1B000000),
	 C(FC000000), C(56000000), C(3E000000), C(4B000000),
	 C(C6000000), C(D2000000), C(79000000), C(20000000),
	 C(9A000000), C(DB000000), C(C0000000), C(FE000000),
	 C(78000000), C(CD000000), C(5A000000), C(F4000000),
	 C(1F000000), C(DD000000), C(A8000000), C(33000000),
	 C(88000000), C(07000000), C(C7000000), C(31000000),
	 C(B1000000), C(12000000), C(10000000), C(59000000),
	 C(27000000), C(80000000), C(EC000000), C(5F000000),
	 C(60000000), C(51000000), C(7F000000), C(A9000000),
	 C(19000000), C(B5000000), C(4A000000), C(0D000000),
	 C(2D000000), C(E5000000), C(7A000000), C(9F000000),
	 C(93000000), C(C9000000), C(9C000000), C(EF000000),
	 C(A0000000), C(E0000000), C(3B000000), C(4D000000),
	 C(AE000000), C(2A000000), C(F5000000), C(B0000000),
	 C(C8000000), C(EB000000), C(BB000000), C(3C000000),
	 C(83000000), C(53000000), C(99000000), C(61000000),
	 C(17000000), C(2B000000), C(04000000), C(7E000000),
	 C(BA000000), C(77000000), C(D6000000), C(26000000),
	 C(E1000000), C(69000000), C(14000000), C(63000000),
	 C(55000000), C(21000000), C(0C000000), C(7D000000)}
};


Z_INLINE zuint8 byte(const zuint32 x, const zuint n)
	{return x >> (n << 3);}


/*----------------------------------------------------------------------------.
| This Algorithm expands the AES key as described in FIPS-197.		      |
| The expanded key size is 240 bytes (maximum of 14 rounds with a unique 16   |
| bytes key schedule plus a 16 bytes key which is used before the 1st round). |
| The decryption key is prepared for the "Equivalent Inverse Cipher" as	      |
| described in FIPS-197. The first slot (16 bytes) of each key (e or d) is    |
| for the initial combination, the second slot for the first round and so on. |
'----------------------------------------------------------------------------*/

#define STAR_X(x)			       \
	 (((x) & Z_UINT32(0x7F7F7F7F)) << 1) ^ \
	((((x) & Z_UINT32(0x80808080)) >> 7) * 0x1B)

#define INVERSE_MIX_COLUMNS(y, x)		   \
	u = STAR_X(x);				   \
	v = STAR_X(u);				   \
	w = STAR_X(v);				   \
	t = w ^ (x);				   \
						   \
	(y) =	(u ^ v ^ w)			 ^ \
		z_uint32_rotate_right(u ^ t,  8) ^ \
		z_uint32_rotate_right(v ^ t, 16) ^ \
		z_uint32_rotate_right(t,     24);

#define LS_BOX					\
	fl[0][byte(t, 0)] ^ fl[1][byte(t, 1)] ^ \
	fl[2][byte(t, 2)] ^ fl[3][byte(t, 3)]


CIPHER_AES_API
void aes_128_set_key(AES128 *object, zuint32 const *key, zusize key_size)
	{
	zuint32 i, t, u, v, w, j, *e = object->e, *d = object->d;

	d[16 + 24] = e[0] = z_uint32_little_endian(key[0]);
	d[16 + 25] = e[1] = z_uint32_little_endian(key[1]);
	d[16 + 26] = e[2] = z_uint32_little_endian(key[2]);
	d[16 + 27] = e[3] = z_uint32_little_endian(key[3]);

	t = e[3];

	for (i = 0; i < 10; ++i)
		{
		t = z_uint32_rotate_right(t, 8);
		t = LS_BOX ^ rco[i];
		t ^= e[4 * i	]; e[4 * i + 4] = t;
		t ^= e[4 * i + 1]; e[4 * i + 5] = t;
		t ^= e[4 * i + 2]; e[4 * i + 6] = t;
		t ^= e[4 * i + 3]; e[4 * i + 7] = t;
		}

	d[0] = e[16 + 24];
	d[1] = e[16 + 25];
	d[2] = e[16 + 26];
	d[3] = e[16 + 27];

	for (i = 4; i < 16 + 24; ++i)
		{
		j = 16 + 24 - (i & ~3) + (i & 3);
		INVERSE_MIX_COLUMNS(d[j], e[i]);
		}
	}


CIPHER_AES_API
void aes_192_set_key(AES192 *object, zuint32 const *key, zusize key_size)
	{
	zuint32 i, t, u, v, w, j, *e = object->e, *d = object->d;

	d[24 + 24] = e[0] = z_uint32_little_endian(key[0]);
	d[24 + 25] = e[1] = z_uint32_little_endian(key[1]);
	d[24 + 26] = e[2] = z_uint32_little_endian(key[2]);
	d[24 + 27] = e[3] = z_uint32_little_endian(key[3]);

	e[4] =	   z_uint32_little_endian(key[4]);
	e[5] = t = z_uint32_little_endian(key[5]);

	for (i = 0; i < 8; ++i)
		{
		t = z_uint32_rotate_right(t, 8);
		t = LS_BOX ^ rco[i];
		t ^= e[6 * i	]; e[6 * i +  6] = t;
		t ^= e[6 * i + 1]; e[6 * i +  7] = t;
		t ^= e[6 * i + 2]; e[6 * i +  8] = t;
		t ^= e[6 * i + 3]; e[6 * i +  9] = t;
		t ^= e[6 * i + 4]; e[6 * i + 10] = t;
		t ^= e[6 * i + 5]; e[6 * i + 11] = t;
		}

	d[0] = e[24 + 24];
	d[1] = e[24 + 25];
	d[2] = e[24 + 26];
	d[3] = e[24 + 27];

	for (i = 4; i < 24 + 24; ++i)
		{
		j = 24 + 24 - (i & ~3) + (i & 3);
		INVERSE_MIX_COLUMNS(d[j], e[i]);
		}
	}


#define LOOP_8_TOP_HALF			      \
	t = z_uint32_rotate_right(t, 8);      \
	t = LS_BOX ^ rco[i];		      \
	t ^= e[8 * i	]; e[8 * i +  8] = t; \
	t ^= e[8 * i + 1]; e[8 * i +  9] = t; \
	t ^= e[8 * i + 2]; e[8 * i + 10] = t; \
	t ^= e[8 * i + 3]; e[8 * i + 11] = t;


CIPHER_AES_API
void aes_256_set_key(AES256 *object, zuint32 const *key, zusize key_size)
	{
	zuint32 i, t, u, v, w, j, *e = object->e, *d = object->d;

	d[32 + 24] = e[0] = z_uint32_little_endian(key[0]);
	d[32 + 25] = e[1] = z_uint32_little_endian(key[1]);
	d[32 + 26] = e[2] = z_uint32_little_endian(key[2]);
	d[32 + 27] = e[3] = z_uint32_little_endian(key[3]);

	e[4] =	   z_uint32_little_endian(key[4]);
	e[5] =	   z_uint32_little_endian(key[5]);
	e[6] =	   z_uint32_little_endian(key[6]);
	e[7] = t = z_uint32_little_endian(key[7]);

	for (i = 0; i < 6; ++i)
		{
		LOOP_8_TOP_HALF;
		t  = e[8 * i + 4] ^ LS_BOX; e[8 * i + 12] = t;
		t ^= e[8 * i + 5];	    e[8 * i + 13] = t;
		t ^= e[8 * i + 6];	    e[8 * i + 14] = t;
		t ^= e[8 * i + 7];	    e[8 * i + 15] = t;
		}

	LOOP_8_TOP_HALF;

	d[0] = e[32 + 24];
	d[1] = e[32 + 25];
	d[2] = e[32 + 26];
	d[3] = e[32 + 27];

	for (i = 4; i < 32 + 24; ++i)
		{
		j = 32 + 24 - (i & ~3) + (i & 3);
		INVERSE_MIX_COLUMNS(d[j], e[i]);
		}
	}


#define STEP(bo, bi, n)				  \
	bo[n] = ft[0][byte(bi[n		 ], 0)] ^ \
		ft[1][byte(bi[(n + 1) & 3], 1)] ^ \
		ft[2][byte(bi[(n + 2) & 3], 2)] ^ \
		ft[3][byte(bi[(n + 3) & 3], 3)] ^ *(k + n);

#define ROUND(bo, bi)	 \
	STEP(bo, bi, 0); \
	STEP(bo, bi, 1); \
	STEP(bo, bi, 2); \
	STEP(bo, bi, 3); \
	k += 4;

#define LAST_STEP(bo, bi, n)			  \
	bo[n] = fl[0][byte(bi[n		 ], 0)] ^ \
		fl[1][byte(bi[(n + 1) & 3], 1)] ^ \
		fl[2][byte(bi[(n + 2) & 3], 2)] ^ \
		fl[3][byte(bi[(n + 3) & 3], 3)] ^ *(k + n);

#define LAST_ROUND(bo, bi)    \
	LAST_STEP(bo, bi, 0); \
	LAST_STEP(bo, bi, 1); \
	LAST_STEP(bo, bi, 2); \
	LAST_STEP(bo, bi, 3);


CIPHER_AES_API
void aes_128_encipher(AES128 *object, zuint32 const *block, zusize block_size, zuint32 *output)
	{
	zuint32 b0[4], b1[4];
	zuint32 const *k;

	for (block_size >>= 4; block_size; block_size--, block += 4, output += 4)
		{
		b0[0] = z_uint32_little_endian(block[0]) ^ object->e[0];
		b0[1] = z_uint32_little_endian(block[1]) ^ object->e[1];
		b0[2] = z_uint32_little_endian(block[2]) ^ object->e[2];
		b0[3] = z_uint32_little_endian(block[3]) ^ object->e[3];

		k = object->e + 4;

		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);

		LAST_ROUND(b0, b1);

		output[0] = z_uint32_little_endian(b0[0]);
		output[1] = z_uint32_little_endian(b0[1]);
		output[2] = z_uint32_little_endian(b0[2]);
		output[3] = z_uint32_little_endian(b0[3]);
		}
	}


CIPHER_AES_API
void aes_192_encipher(AES192 *object, zuint32 const *block, zusize block_size, zuint32 *output)
	{
	zuint32 b0[4], b1[4];
	zuint32 const *k;

	for (block_size >>= 4; block_size; block_size--, block += 4, output += 4)
		{
		b0[0] = z_uint32_little_endian(block[0]) ^ object->e[0];
		b0[1] = z_uint32_little_endian(block[1]) ^ object->e[1];
		b0[2] = z_uint32_little_endian(block[2]) ^ object->e[2];
		b0[3] = z_uint32_little_endian(block[3]) ^ object->e[3];

		k = object->e + 4;

		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);

		LAST_ROUND(b0, b1);

		output[0] = z_uint32_little_endian(b0[0]);
		output[1] = z_uint32_little_endian(b0[1]);
		output[2] = z_uint32_little_endian(b0[2]);
		output[3] = z_uint32_little_endian(b0[3]);
		}
	}


CIPHER_AES_API
void aes_256_encipher(AES256 *object, zuint32 const *block, zusize block_size, zuint32 *output)
	{
	zuint32 b0[4], b1[4];
	zuint32 const *k;

	for (block_size >>= 4; block_size; block_size--, block += 4, output += 4)
		{
		b0[0] = z_uint32_little_endian(block[0]) ^ object->e[0];
		b0[1] = z_uint32_little_endian(block[1]) ^ object->e[1];
		b0[2] = z_uint32_little_endian(block[2]) ^ object->e[2];
		b0[3] = z_uint32_little_endian(block[3]) ^ object->e[3];

		k = object->e + 4;

		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);

		LAST_ROUND(b0, b1);

		output[0] = z_uint32_little_endian(b0[0]);
		output[1] = z_uint32_little_endian(b0[1]);
		output[2] = z_uint32_little_endian(b0[2]);
		output[3] = z_uint32_little_endian(b0[3]);
		}
	}


#undef STEP
#undef ROUND
#undef LAST_STEP
#undef LAST_ROUND

#define STEP(bo, bi, n)				  \
	bo[n] = it[0][byte(bi[n		 ], 0)] ^ \
		it[1][byte(bi[(n + 3) & 3], 1)] ^ \
		it[2][byte(bi[(n + 2) & 3], 2)] ^ \
		it[3][byte(bi[(n + 1) & 3], 3)] ^ *(k + n);

#define ROUND(bo, bi)	 \
	STEP(bo, bi, 0); \
	STEP(bo, bi, 1); \
	STEP(bo, bi, 2); \
	STEP(bo, bi, 3); \
	k += 4;

#define LAST_STEP(bo, bi, n)			  \
	bo[n] = il[0][byte(bi[n		 ], 0)] ^ \
		il[1][byte(bi[(n + 3) & 3], 1)] ^ \
		il[2][byte(bi[(n + 2) & 3], 2)] ^ \
		il[3][byte(bi[(n + 1) & 3], 3)] ^ *(k + n);

#define LAST_ROUND(bo, bi)    \
	LAST_STEP(bo, bi, 0); \
	LAST_STEP(bo, bi, 1); \
	LAST_STEP(bo, bi, 2); \
	LAST_STEP(bo, bi, 3);


CIPHER_AES_API
void aes_128_decipher(AES128 *object, zuint32 const *block, zusize block_size, zuint32 *output)
	{
	zuint32 b0[4], b1[4];
	zuint32 const *k;

	for (block_size >>= 4; block_size; block_size--, block += 4, output += 4)
		{
		b0[0] = z_uint32_little_endian(block[0]) ^ object->d[0];
		b0[1] = z_uint32_little_endian(block[1]) ^ object->d[1];
		b0[2] = z_uint32_little_endian(block[2]) ^ object->d[2];
		b0[3] = z_uint32_little_endian(block[3]) ^ object->d[3];

		k = object->d + 4;

		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);

		LAST_ROUND(b0, b1);

		output[0] = z_uint32_little_endian(b0[0]);
		output[1] = z_uint32_little_endian(b0[1]);
		output[2] = z_uint32_little_endian(b0[2]);
		output[3] = z_uint32_little_endian(b0[3]);
		}
	}


CIPHER_AES_API
void aes_192_decipher(AES192 *object, zuint32 const *block, zusize block_size, zuint32 *output)
	{
	zuint32 b0[4], b1[4];
	zuint32 const *k;

	for (block_size >>= 4; block_size; block_size--, block += 4, output += 4)
		{
		b0[0] = z_uint32_little_endian(block[0]) ^ object->d[0];
		b0[1] = z_uint32_little_endian(block[1]) ^ object->d[1];
		b0[2] = z_uint32_little_endian(block[2]) ^ object->d[2];
		b0[3] = z_uint32_little_endian(block[3]) ^ object->d[3];

		k = object->d + 4;

		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);

		LAST_ROUND(b0, b1);

		output[0] = z_uint32_little_endian(b0[0]);
		output[1] = z_uint32_little_endian(b0[1]);
		output[2] = z_uint32_little_endian(b0[2]);
		output[3] = z_uint32_little_endian(b0[3]);
		}
	}


CIPHER_AES_API
void aes_256_decipher(AES256 *object, zuint32 const *block, zusize block_size, zuint32 *output)
	{
	zuint32 b0[4], b1[4];
	zuint32 const *k;

	for (block_size >>= 4; block_size; block_size--, block += 4, output += 4)
		{
		b0[0] = z_uint32_little_endian(block[0]) ^ object->d[0];
		b0[1] = z_uint32_little_endian(block[1]) ^ object->d[1];
		b0[2] = z_uint32_little_endian(block[2]) ^ object->d[2];
		b0[3] = z_uint32_little_endian(block[3]) ^ object->d[3];

		k = object->d + 4;

		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);
		ROUND(b0, b1);
		ROUND(b1, b0);

		LAST_ROUND(b0, b1);

		output[0] = z_uint32_little_endian(b0[0]);
		output[1] = z_uint32_little_endian(b0[1]);
		output[2] = z_uint32_little_endian(b0[2]);
		output[3] = z_uint32_little_endian(b0[3]);
		}
	}


#if defined(CIPHER_AES_BUILD_ABI) || defined(CIPHER_AES_BUILD_MODULE_ABI)

	CIPHER_AES_ABI ZCipherABI const abi_cipher_aes_128 = {
		/* test_key		 */ NULL,
		/* set_key		 */ (ZCipherSetKey )aes_128_set_key,
		/* encipher		 */ (ZCipherProcess)aes_128_encipher,
		/* decipher		 */ (ZCipherProcess)aes_128_decipher,
		/* enciphering_size	 */ NULL,
		/* deciphering_size	 */ NULL,
		/* instance_size	 */ sizeof(AES128),
		/* key_minimum_size	 */ AES_128_KEY_SIZE,
		/* key_maximum_size	 */ AES_128_KEY_SIZE,
		/* key_word_size	 */ AES_128_KEY_SIZE,
		/* enciphering_word_size */ AES_WORD_SIZE,
		/* deciphering_word_size */ AES_WORD_SIZE,
		/* features		 */ FALSE
	};

	CIPHER_AES_ABI ZCipherABI const abi_cipher_aes_192 = {
		/* test_key		 */ NULL,
		/* set_key		 */ (ZCipherSetKey )aes_192_set_key,
		/* encipher		 */ (ZCipherProcess)aes_192_encipher,
		/* decipher		 */ (ZCipherProcess)aes_192_decipher,
		/* enciphering_size	 */ NULL,
		/* deciphering_size	 */ NULL,
		/* instance_size	 */ sizeof(AES192),
		/* key_minimum_size	 */ AES_192_KEY_SIZE,
		/* key_maximum_size	 */ AES_192_KEY_SIZE,
		/* key_word_size	 */ AES_192_KEY_SIZE,
		/* enciphering_word_size */ AES_WORD_SIZE,
		/* deciphering_word_size */ AES_WORD_SIZE,
		/* features		 */ FALSE
	};

	CIPHER_AES_ABI ZCipherABI const abi_cipher_aes_256 = {
		/* test_key		 */ NULL,
		/* set_key		 */ (ZCipherSetKey )aes_256_set_key,
		/* encipher		 */ (ZCipherProcess)aes_256_encipher,
		/* decipher		 */ (ZCipherProcess)aes_256_decipher,
		/* enciphering_size	 */ NULL,
		/* deciphering_size	 */ NULL,
		/* instance_size	 */ sizeof(AES256),
		/* key_minimum_size	 */ AES_256_KEY_SIZE,
		/* key_maximum_size	 */ AES_256_KEY_SIZE,
		/* key_word_size	 */ AES_256_KEY_SIZE,
		/* enciphering_word_size */ AES_WORD_SIZE,
		/* deciphering_word_size */ AES_WORD_SIZE,
		/* features		 */ FALSE
	};

#endif

#if defined(CIPHER_AES_BUILD_MODULE_ABI)

#	include <Z/ABIs/generic/module.h>

	static ZModuleUnit const units[] = {
		{"AES128", "AES-128", Z_VERSION(1, 0, 0), &abi_cipher_aes_128},
		{"AES192", "AES-192", Z_VERSION(1, 0, 0), &abi_cipher_aes_192},
		{"AES256", "AES-256", Z_VERSION(1, 0, 0), &abi_cipher_aes_256}
	};

	static ZModuleDomain const domain = {"Cipher", Z_VERSION(1, 0, 0), 3, units};
	Z_API_WEAK_EXPORT ZModuleABI const __module_abi__ = {1, &domain};

#endif


/* AES.c EOF */
